2016-07-19 4 views
0

J'essaie de faire une application comme "Heads up" juste pour plus d'exercice !! Mais maintenant je faisais face à un problème logique dans l'utilisation accéléromètre dans mon application. Je veux que le toast soit "correct" quand il est incliné (l'accéléromètre donne -7 dans cette position) et que le toast soit "faux" quand l'inclinaison est relevée (l'accéléromètre donne 7 ou plus dans cette position).Problème de logique lors de l'utilisation de l'accéléromètre

Mais le problème était que l'application toast plusieurs fois à plusieurs reprises dans chaque position. J'ai donc utilisé un booléen (isToasted) pour faire griller l'application une fois dans chacune de ces positions. Mais maintenant, il ne trinque pas du tout!

Où est mon problème et que dois-je faire?

ceci est une partie de mes codes:

Boolean isToasted = false; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    int sensorValue = (int) event.values[2]; 

    while (isToasted) { 
     switch (sensorValue) { 
      case 7: { 
       Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show(); 
       isToasted = true; 
       break; 
      } 
      case -7: { 
       Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show(); 
       isToasted = true; 
       break; 
      } 
     } 
    } 
    if (sensorValue == 0) isToasted = false; //sensorValue = 0 means device is not tilted and it's in direct position. 
} 
+0

les journaux d'erreurs ou trace de pile? – Shek

+0

il n'y a pas de journal d'erreurs –

+0

isToasted ne sera jamais vrai avec votre code actuel. Il est défini sur false par défaut. – Compass

Répondre

0

La raison pour laquelle il afficherait les Toast plusieurs fois dans chaque position est parce qu'un SensorEvent peut se produire multiple times à une position unique:

Notez que « le changement » est un peu un abus de langage, car cela sera également appelé si nous avons une nouvelle lecture d'un capteur avec exactement les mêmes valeurs de capteur (mais un horodatage plus récent).

Par conséquent, chaque fois qu'il ya un SensorEvent qui a l'une des valeurs z que vous avez spécifié dans votre instruction switch un Toast sera affiché. Vous étiez sur la bonne voie en ajoutant une valeur boolean pour savoir si le message était déjà affiché, mais la boucle while que vous avez ne sera jamais exécutée car isToasted est défini sur false.

En fait, vous n'avez même pas besoin d'une boucle. Tout ce que vous avez à faire est de vérifier si la valeur z est comprise entre deux valeurs. Si c'est le cas, définissez boolean sur true. Sinon, vous vérifiez si la valeur boolean est vraie et si la valeur z est supérieure ou inférieure à la plage. Vous pouvez ensuite définir le Toast en conséquence et définir le boolean sur false afin que le message ne s'affiche pas une deuxième fois.

private boolean isReset = true; 
private float mMaxValue = 7; 
private float mDeadZone = 5; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    float value = event.values[2]; 

    if(value >= mDeadZone || value <= -mDeadZone) { 
     if(isReset && value <= -mMaxValue) { 
      Toast.makeText(find_word2.this, "correct", Toast.LENGTH_SHORT).show(); 
      isReset = false; 
     } else if(isReset && value >= mMaxValue) { 
      Toast.makeText(find_word2.this, "wrong", Toast.LENGTH_SHORT).show(); 
      isReset = false; 
     } 
    } else { 
     isReset = true; 
    } 
} 

Vous pouvez aussi créer une « zone morte » en faisant la plage dans la déclaration if extérieure inférieure à la valeur maximale. Cela garantirait que l'utilisateur devrait réinitialiser l'appareil plus près de zéro avant que le Toast puisse être affiché à nouveau.

+0

ah merci. J'ai essayé ça et maintenant ça marche bien en montrant "mauvais" mais ça ne grille pas "correct" du tout! –

+0

@ahmadmohseni Ah, ma faute. La 'valeur' aurait dû être enveloppée dans une fonction' Math.abs() ', ou simplement utiliser un simple opérateur' || '. J'ai édité la réponse, cela devrait fonctionner maintenant. – Bryan

+0

@ahmadmohseni J'ai fait un simple [violon] (http://ideone.com/wuLL20) qui imite 'onSensorChanged'. Il sort la valeur z "SensorEvent", ainsi que "correct" si la valeur est égale ou inférieure à -7 et "fausse" si la valeur est égale ou supérieure à 7. Dans ce cas, 'isReset' est toujours vrai car Je réinitialise toujours la valeur à zéro après chaque appel. – Bryan

0

La différence entre do-temps et tout est que do-while évalue son expression au fond de la boucle au lieu du sommet. Par conséquent, les instructions dans le bloc Do sont toujours exécutées au moins .

+0

Cela créera une boucle infinie pour chaque appel à 'onSensorChanged()' parce que 'sensorValue' ne change jamais pendant un seul appel. Si vous supprimez entièrement la boucle, cela devrait fonctionner comme prévu. – Bryan

+0

@Bryan vous avez raison – Shek