Skocz do zawartości
patlas

Sprawdzenie długości zasłonięcia czujnika odległości

    Rekomendowane odpowiedzi

    patlas

    Witam :)

    Mam dość specyficzny problem z rozpoznawaniem długości zasłonięcia czujnika odległości w telefonie (ten który wygasza wyświetlacz podczas rozmowy). Chciałbym za jego pomocą sterować aplikacją. Miałaby ona działać na takiej zasadzie że rozpoznaje krótko i długotrwałe zasłonięcie tegoż sensora (wówczas dystans wynosi mniej niż 1cm lub więcej). Do tego celu używam wątku który po wykryciu zasłonięcia czujnika czeka 300ms i sprawdza ponownie jeśli tak to wykryto długie zasłonięcie jeśli nie to krótkie. Niestety mój program nie działa do końca. Zamo wykrywanie zdarzenia zasłonięcia mi działa tak rozpoznawanie go w wątku już nie :(

    Oto mój kod:

    public class NextActivity extends Activity implements SensorEventListener {
    
       private static final String TAG = "DISTANCE";
       private SensorManager mSensorManager;
       private Sensor mProximity;
       public TextView tv;
       public TextView tv2;
       public int check=0;
       float distance=0;
       public float eventTime;
       public MyThread thread;
    
       @Override
       public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_next);  
    
           mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
           mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    
           tv = (TextView)findViewById(R.id.textView1);
           tv2= (TextView)findViewById(R.id.textView2);
           thread = new MyThread();
           thread.start();
       }
    
    
     public final void onSensorChanged(SensorEvent event) {
       distance = event.values[0];
           tv.setText(""+thread.isAlive());
     }
    
    
    
     @Override
     protected void onResume() {
       // Register a listener for the sensor.
       super.onResume();
       mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
     }
    
     @Override
     protected void onPause() {
       // Be sure to unregister the sensor when the activity pauses.
       super.onPause();
       mSensorManager.unregisterListener(this);
     }
    
       public class MyThread extends Thread {
    
           @Override
           public void run() {
               while(true){
               if(distance<1) 
               {
                   long time = System.currentTimeMillis();
                   while(System.currentTimeMillis()<time+300);
                   if(distance<1)
                   {   
                       tv.setText("DOUBLE -> NEXT"); 
                       distance=5;
                   } else tv.setText("ONCE -> BACK");      
               }else tv.setText("NONE CLICKED");
               }}
       }
    
    }
    
    

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Nie wiem jakie jest do końca założenie programu, ale część wyświetlania znajduje się w wątku np. tv.setText("DOUBLE -> NEXT");

    Podczas wyświetlania obiekt View sprawdza czy został wykonany w odpowiednim wątku. W tym przypadku w tym którym go utworzono. Najwygodniej utworzyć Handler w głównym wątku i w obiekcie MyThread przesłać wyświetlanie do Handlera. W funkcji onSensorChanged znajduje się tv.setText(""+...) które usunie poprzednie wpisy - tutaj wyświetlamy w dobrym wątku.

    W obiekcie NextActivity można utworzyć Handler tj.

    Handler mHandler = new Handler();

    Następnie w wątku dodatkowym MyThread wstawiamy wyświetlanie do kolejki głównego wątku np.

    mHandler.post(new Runnable(){
    pubic void run(){
     tv.setText("DOUBLE -> NEXT");
    }
    });
    

    itp.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    patlas

    Wszystko ładnie działa ale jest jeden problem gdy dopisze to samo dla 2 przypadku wyświetlania texedit oto mój kod:

    public class MyThread extends Thread {
    
    	int x=0;
    	@Override
    	public void run() {
    		while(true){
    
    
    		if(distance<1) 
    		{
    			long time = System.currentTimeMillis();
    			while(System.currentTimeMillis()<time+150);
    			if(distance<1)
    			{	
    				[b]mHandler.post(new Runnable(){
    					public void run(){tv.setText("DOUBLE -> NEXT");}});[/b]
    
    			} 
    			else
    			{   
    				[b]mHandler.post(new Runnable(){
    			public void run(){tv.setText("ONCE -> BACK");}});[/b]		
    		}
    		}}
    }
    

    W takim przypadku kompilator wywala mi komunikat że za dużo metod run() i proponuje o zmiane jej nazwy...

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeżeli tak jest możesz zdefiniować metody runnable na zewnątrz klasy tj.

    Runnable r0 = new Runnable(){
    public void run(){
         tv.setText("DOUBLE -> NEXT");
    }
    
    Runnable r1 = new Runnable(){
    public void run(){
         tv.setText("ONCE -> BACK");
    }
    

    I teraz umieść je w kolejce:

    if(distance<1)
    			{	
    				mHandler.post(r0);
    
    			} 
    			else
    			{   
    				mHandler.post(r1);
    }
    

    Względnie otocz instrukcję warunkową metodą runnable.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    patlas

    Bardzo dziękuje :) teraz ładnie działa :)

    Korzystając z założonego tematu chciałbym zapytać o jeszcze jedną rzecz z która mam poniekąd problem.

    Mianowicie chodzi u użycie sendKeyDownUpSync(KeyEvent.KEYCODE_MEDIA_PREVIOUS) dzięki której chce zdalnie z mojego programu zmieniać muzkę odtwarzana przez odtwarzacz androida czy też HTC (działają identycznie).

    Moja funkcja wygląda następująco:

    public void previousTruck()
       {
       	new Thread(new Runnable() {         
               public void run() {                 
                   new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
               }   
           }).start();  	
       }

    Jak napisałem wyżej działa poniekąd dobrze gdyż zmienia utwory a nie jeden utwór jak bym chciał. Jednorazowe wywołanie funkcji previousTruck() powoduje przeskakiwanie odtwarzacza na różne utwory (po kolei w liście) a chciałbym aby przeskok dokonany był jednokrotnie :)

    Pozdrawiam i z góry dziękuje :)

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Przenoszę do odpowiedniego działu...

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Ostatnio przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.

    x