68 votes

Android accéléromètre ne fonctionne pas lorsque l'écran est éteint

Je suis du développement d'une application pour mon mémoire de fin d'études en informatique, et j'ai besoin de recueillir et de journal de données d'accélérométrie de l'. J'ai besoin de l'acquérir pour un tout au long de la journée, donc il y a de sérieuses contraintes d'autonomie de batterie (par exemple, je ne peux pas quitter l'écran). Aussi, ce n'est pas un marché cible de l'application, de sorte qu'il est assez acceptable pour faire un peu de sérieux de piratage, même de bas niveau C/C++, si nécessaire.

Il est bien connu que sur beaucoup d'appareils les auditeurs pour des événements d'accéléromètre cesse de générer des événements lorsque l'écran s'éteint (quelques liens concernant ce problème: http://code.google.com/p/android/issues/detail?id=3708 , Accéléromètre cesse de remise des échantillons lorsque l'écran est éteint sur Droid/Nexus One, même avec un WakeLock). J'ai bien cherché des alternatives, certains d'entre eux comprennent des solutions de contournement ne fonctionne pas pour mon périphérique (LG P990, ROM stock).

Donc ce qui se passe ceci: Lorsque vous vous inscrivez un écouteur d'événement pour android accéléromètre capteur dans un Service, il fonctionne très bien jusqu'à ce que l'écran est éteint. J'ai déjà essayé d'enregistrer l'eventListener sur un Service, sur un IntentService, a essayé d'acquérir des WakeLocks. Concernant les wakelocks, je peux vérifier que le service est encore en cours d'exécution en regardant le LOGcat de sortie, mais il semble que l'accéléromètre est mis en mode veille. L'une des solutions de contournement présentés dans certains des liens est d'annuler l'inscription et ré-enregistrer l'écouteur d'événement à intervalles réguliers en utilisant le fil d'une IntentService comme dans cet extrait de code soufflet

synchronized private static PowerManager.WakeLock getLock(Context context) {
    if (lockStatic==null) {
        PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);

        lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
        lockStatic.setReferenceCounted(true);
    }

    return(lockStatic);
}

@Override
protected void onHandleIntent(Intent intent) {

     sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
     sensorManager.unregisterListener(this);
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);


    synchronized (this) {
        boolean run = true;
        while (run){
            try {
                wait(1000);
                getLock(AccelerometerService.this).acquire();
                sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
                sensorManager.unregisterListener(this);
                sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
                Log.d("Accelerometer service", "tick!");

            } catch (Exception e) {
                run = false;
                Log.d("Accelerometer service", "interrupted; cause: " + e.getMessage());


            }
        }
    }       
}


@Override
public void onSensorChanged(SensorEvent event) {
    Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," +  event.values[2]);
}

ce qui rend en effet la onSensorChange être appelée à chaque fois que nous annuler l'enregistrement/enregistrement de l'écouteur. Le problème est que la réception de l'événement contient toujours les mêmes valeurs, indépendamment de moi, les secousses de l'appareil.

Donc, en gros, mes questions sont les suivantes: ( garder avec moi, je suis presque fini :P )

  1. est-il possible d'avoir accès de bas niveau (C/C++ approche) à l'accéléromètre du matériel SANS vous inscrire à un écouteur d'événement?

  2. est-il un autre solution de contournement ou de hack?

  3. quelqu'un pourrait-il avec un plus up-to-date de téléphone de bien vouloir tester si le problème persiste dans le firmware 3.0 et ci-dessus?

[Mise à JOUR]

Malheureusement, il semble y avoir un bug avec certains téléphones portables. Plus de détails dans ma réponse.

68voto

martin Points 776

Ok, j'ai donc créé une réponse à ma question, comme demandé par le Renard.

En gros, c'est un problème avec mon téléphone. D'autres utilisateurs ont signalé cela arrive aussi avec leurs téléphones, de marques différentes, mais même version d'Android. Autres personnes n'ont aucun problème à tous - fortement en indiquant que ce n'est pas un problème avec la version stock d'android, mais à partir de la mise en œuvre de chaque entreprise pour leur pilotes de matériel.

J'ai besoin constant de données d'accélérométrie de l'livré et ne peuvent pas avoir un dongle mesurer ces données pour moi - j'ai un Arduino bluetooth et d'un accéléromètre, si je pouvais avoir mis en œuvre cette solution. J'ai donc décidé que la solution temporaire pour mon téléphone portable a été de laisser l'écran allumé (en grisé) et d'ignorer la batterie consuption. Plus tard, je vais faire les tests pour l'utilisation de la batterie à l'aide d'un autre téléphone android qui fonctionne avec l'écran éteint.

Plus d'informations sur le bug

J'ai fait des recherches et trouvé des rapports provenant d'autres utilisateurs d'Android et je pense que je suis peut-être comprendre ce qui se passe. La bibliothèque libsensors.alors, qui a les pilotes pour les capteurs téléphone n'est pas développé par google, mais par chaque téléphone cellulaire fournisseur de cours, parce que chaque téléphone portable possède son propre matériel spécifique. Google fournit uniquement un fichier en-tête C afin que les développeurs savent ce qu'ils ont à mettre en œuvre. Dans certaines implémentations de ces pilotes, les développeurs il suffit de tourner l'accéléromètre éteint lorsque l'écran s'éteint, l'empêchant ainsi le capteur de l'écouteur d'événement pour recevoir de nouveaux événements.

J'ai aussi testé avec CyanogenMod RC7.2 mais il ne fonctionne pas non plus, parce que l'accéléromètre pilotes sont d'origine LG.

Les E-mails échangés avec le service RH de LG

J'ai envoyé un e-mail aux développeurs du LG P990 et a finalement obtenu des réponses concrètes! Cela peut être d'une grande aide pour certaines personnes comme moi qui sont confrontés à ces questions avec Android. J'ai écrit à la question suivante

Bonjour! Je suis l'élaboration de ma thèse en informatique et actuellement je suis d'extraire des données de l'accéléromètre de matériel. Maintenant, j'ai découvert que les accéléromètres ne pas envoyer des événements lorsque l'écran est éteint, de sorte même quand je prends un wakelock de dans un de mes programmes, je peux vérifiez que mon programme est toujours en cours d'exécution (par le biais de LOGcat de sortie), mais pas de l'accéléromètre de l'événement qui vient de sortir. J'ai pour estomper mon écran (qui je ne peut pas se le permettre, la batterie se décharge trop rapide) pour démarrer receiveing accéléromètre événements de nouveau. J'ai aussi essayé d'y accéder à travers le C code, l'inscription sur les événements d'accéléromètre mais le résultat était le de même, l'accéléromètre ne pas jeter des valeurs, même si j'ai été la rotation de mon appareil. Alors je me demandais si je pouvais avoir un accès direct pour le matériel, avec du code natif, sans avoir à s'inscrire à un auditeur. Est-ce possible? Si oui, pourriez-vous l'obligeance de nous donner quelques des conseils? Je serais très reconnaissante de toute l'aide! Martin

Pour ce que j'ai reçu cette réponse:

Cher Martin, Nous avons reçu la réponse d'un Dev. De l'équipe. Ils ont dit que vous ne peut pas obtenir de l'accéléromètre de l'événement, tandis que l'écran de votre téléphone est éteint. Parce que HAL couche ne pas mettre en œuvre sysFS chemin pour arriver H/W événement tel que accéléromètre et il n'y a pas d'API publique pour obtenir de l'événement. Je vous remercie. Meilleur Ce qui concerne. (Sean Kim)

J'ai ensuite envoyé un e-mail de retour, en disant entre autres choses, que je considérais comme c'est un bug, puisque l'on devrait avoir accès à toutes les hadware lors de l'acquisition d'un signal de verrouillage:

[...] J'ai posé cette question parce que j'ai des amis qui ont aussi des Les téléphones Android avec la même version de pain d'épice, mais d'autres marques de téléphone portable, et certains d'entre eux ont déclaré recevoir des événements de les accéléromètres lorsque l'écran est éteint. J'ai lu sur certains les forums que ce bug je considère comme un bug, car quand je l'acquisition d'une Wakelock je m'attends à avoir un traitement en cours - dépend le capteur de pilotes que les fournisseurs mettent en oeuvre pour leurs téléphones cellulaires. Est il y a une possibilité que ces pilotes peuvent être mis à jour ou cela bug sera corrigé à un certain point? Cela m'aiderait énormément avec mon travaux en cours [...]

Et puis j'ai reçu cette réponse:

À ma connaissance, à partir de Dev. L'équipe, Qui n'est pas un bug. C'est sans limite de ce téléphone parce que de H/W architecture. Nous avons besoin de redessiner le HAL de l'architecture et du pilote de périphérique à l'appui de votre demande. Mais, comme vous le sais que c'est trop difficile en raison du manque de ressources. Nous essayons de vous aider grâce à nos efforts, mais nous ne pouvons pas l'appui de votre demande comme je l'ai mentionné. (Sean Kim)

Donc, apparemment, ils savent à ce sujet, mais ne sont pas en essayant de corriger ce soit parce qu'ils ne pense pas que c'est un bug que je crois fermement est une logique de faille - ou qu'ils n'ont pas le temps ou les ressources pour la corriger.

La ligne de fond Si vous avez un téléphone cellulaire qui n'envoie pas des événements d'accéléromètre avec le scren, essayez de mettre à jour votre firmware. Si cela ne résout pas et que vous voulez vraiment faire quelque grave piratage, re mettre en œuvre votre matériel de couche - indice: c'est probablement quelque chose à voir avec libsensors.donc

J'espère que cela peut aider quelqu'un d'avoir les mêmes problèmes. Martin

6voto

fu-fu Points 21

Je ne sais pas si ce sera effectivement vous aider, mais j'ai trouvé un travail autour (Pas sûr de savoir comment bien s'aidera de l'économie de la batterie).

Avec bash, j'ai une boucle while chat-ing /sys/devices/virtual/accelerometer/accelerometer/acc_file, et lorsque je désactive l'écran via le bouton d'alimentation de la sortie continue, mais est gelé. (J'ai eu sshd cours d'exécution dans un chroot de là, l'être capable de le voir.)

Toutefois, en écho 0 > /sys/devices/platform/msm_fb.196609/leds/lcd-backlight/brightness. L'écran s'éteint, et la sortie est continue.

C'est sur un SGH-T589W, la version android 2.3.6.

(Désolé si ce n'est pas aux normes, mais (je pense), il obtient le point à travers et qu'il pourrait être utile pour quelqu'un dans l'avenir peut-être.)

2voto

Greg Martin Points 21

J'ai couru dans des problèmes similaires avec le Samsung Nexus sous Android 4.0.2 à l'aide d'autres services du système stop/pause pendant que l'écran est désactivé, même si un PARTIAL_WAKE_LOCK est acquis. Ma solution a été d'utiliser un SCREEN_DIM_WAKE_LOCK comme dans:

 lockStatic = mgr.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,NAME);

Il serait de loin préférable d'avoir l'écran entièrement éteint, mais au moins, cette solution fonctionne mais il serait encore mieux si je pouvais limiter à l'aide d'un SCREEN_DIM_WAKE_LOCK uniquement aux dispositifs/Systèmes d'exploitation qui en ont besoin.

0voto

EvilDuck Points 2144

J'ai hate de vous décevoir, mais certains appareils, il suffit de ne pas garder acceleromet pendant qu'ils sont dans un mode de sommeil. Certains le font, d'autres pas. Vous pouvez consulter toutes les podomètre de perte de poids de l'app sur le magasin de la plupart d'entre eux affirment explicitement que cela ne peut pas fonctionner sur certains appareils.

0voto

Brans Points 87

Comment pensez-vous. Peut aider à ijection de l'écran sur les événements de la volonté de l'écran est vraiment éteint? L'injection de screen_on événement afin d'effectuer des travaux de capteurs lorsque l'écran est éteint

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X