0

Consider the following:

package com.example.savag.bcapplication;

import android.app.Activity;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    //define global variable types
    int counter = 9;
    String strcounter;
    int buttoncounter = 0;
    String strbcounter;

    //Define the sensor Manager
    SensorManager sm;

    //Define the Motion Sensor objects
    Sensor accelerometer;
    Sensor gravity;
    Sensor gyroscope;
    Sensor uncalgyro;
    Sensor lineaccel;
    Sensor rotatevector;
    Sensor sigmotion;
    Sensor stepcounter;
    Sensor stepdetector;
    //Define the changing Motion Sensor text values

    //Define the position sensor objects
    Sensor gamerotatevector;



    ImageButton arrowup;
    ImageButton arrowdown;
    ImageView navbar;
    TextView dynamictext;
    TextView dynamicheader;
    private final Handler handler = new Handler();
    SenseThread myThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Need to declare here if findviewbyid is being run
        arrowup = (ImageButton) findViewById(R.id.uparrow);
        arrowdown = (ImageButton) findViewById(R.id.downarrow);
        navbar = (ImageView) findViewById(R.id.infospace);
        dynamictext = (TextView) findViewById(R.id.dynamictxt);
        dynamicheader = (TextView) findViewById(R.id.dynamiched);
        //Global counter variables
        counter = 9;
        strcounter = Integer.toString(counter);
        buttoncounter = 0;
        strbcounter = Integer.toString(buttoncounter);
        //Set Nav bar invisible for now
        arrowup.setVisibility(View.GONE);
        arrowdown.setVisibility(View.GONE);
        navbar.setVisibility(View.GONE);
        dynamictext.setVisibility(View.GONE);
        dynamicheader.setVisibility(View.GONE);
        sm = (SensorManager) getSystemService(SENSOR_SERVICE);
        myThread = new SenseThread();
        myThread.start();

        arrowup.setOnClickListener( //This is for the up arrow
                new ImageButton.OnClickListener() {
                    public void onClick(View v) {
                        if ((strcounter.equals("10")) || (strcounter.equals("9"))) { //Further than limit or limit
                            //do nothing if strcounter is 10 or 9
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("8"))) { // Check if we are on limit and motion button
                            if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Acceleration:");
                                sm.registerListener(MainActivity.this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 9 (limit)
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("7"))) {
                            sm.unregisterListener(MainActivity.this, gyroscope);
                            if (sm.getSensorList(Sensor.TYPE_ROTATION_VECTOR).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Rotation Vector:");
                                sm.registerListener(MainActivity.this, rotatevector, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_ROTATION_VECTOR).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 8
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("6"))) {
                            sm.unregisterListener(MainActivity.this, gravity);
                            if (sm.getSensorList(Sensor.TYPE_GYROSCOPE).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Gyroscope:");
                                sm.registerListener(MainActivity.this, gyroscope, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_GYROSCOPE).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 7
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("5"))) {
                            sm.unregisterListener(MainActivity.this, sigmotion);
                            if (sm.getSensorList(Sensor.TYPE_GRAVITY).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Gravity Sensor:");
                                sm.registerListener(MainActivity.this, gravity, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_GRAVITY).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 6
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("4"))) {
                            sm.unregisterListener(MainActivity.this, lineaccel);
                            if (sm.getSensorList(Sensor.TYPE_SIGNIFICANT_MOTION).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Significant Motion:");
                                sm.registerListener(MainActivity.this, sigmotion, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_SIGNIFICANT_MOTION).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 5
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("3"))) {
                            sm.unregisterListener(MainActivity.this, uncalgyro);
                            if (sm.getSensorList(Sensor.TYPE_LINEAR_ACCELERATION).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Linear Acceleration:");
                                sm.registerListener(MainActivity.this, lineaccel, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_LINEAR_ACCELERATION).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 4
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("2"))) {
                            if (sm.getSensorList(Sensor.TYPE_GYROSCOPE_UNCALIBRATED).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Uncalibrated Gyroscope:");
                                sm.registerListener(MainActivity.this, uncalgyro, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_GYROSCOPE_UNCALIBRATED).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 3
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            //return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("1"))) {
                            sm.unregisterListener(MainActivity.this, stepdetector);
                            if (sm.getSensorList(Sensor.TYPE_STEP_COUNTER).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Steps Counted:");
                                sm.registerListener(MainActivity.this, stepcounter, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_STEP_COUNTER).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 2
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                            return;
                        }
                        if ((strbcounter.equals("1")) && (strcounter.equals("0"))) {
                            if (sm.getSensorList(Sensor.TYPE_STEP_DETECTOR).size() != 0) { // Add check to see if we have this sensor
                                dynamicheader.setText("Steps Detected:");
                                sm.registerListener(MainActivity.this, stepdetector, SensorManager.SENSOR_DELAY_NORMAL, myThread.handler2);
                            } else if (sm.getSensorList(Sensor.TYPE_STEP_DETECTOR).size() == 0) {
                                dynamictext.setText("Sensor not detected");
                            }
                            counter++; //Increment to 1
                            strcounter = Integer.toString(counter); // Set the appropriate conversion
                        }
                    }
                }
        );

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + " MS^-2 \nY: " + event.values[1] + " MS^-2 \nZ: " + event.values[2] + " MS^-2");
        } else if (sm.getSensorList(Sensor.TYPE_ROTATION_VECTOR).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + "\nY: " + event.values[1] + "\nZ: " + event.values[2] + "scalar: " + event.values[3]);
        } else if (sm.getSensorList(Sensor.TYPE_GYROSCOPE).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + " rad/s \nY: " + event.values[1] + " rad/s \nZ: " + event.values[2] + " rad/s");
        } else if (sm.getSensorList(Sensor.TYPE_GRAVITY).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + " MS^-2 \nY: " + event.values[1] + " MS^-2 \nZ: " + event.values[2] + " MS^-2");
        }
        //else if (sm.getSensorList(Sensor.TYPE_GRAVITY).size() != 0) { // significant motion needs a different process
        //    TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
        //    dynamictext.setText("X: " + event.values[0] + "\nY: " + event.values[1] + "\nZ: " + event.values[2]);
        //}
        else if (sm.getSensorList(Sensor.TYPE_LINEAR_ACCELERATION).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + " MS^-2 \nY: " + event.values[1] + " MS^-2 \nZ: " + event.values[2] + " MS^-2");
        } else if (sm.getSensorList(Sensor.TYPE_GYROSCOPE_UNCALIBRATED).size() != 0) {
            TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
            dynamictext.setText("X: " + event.values[0] + " rad/s \nY: " + event.values[1] + " rad/s \nZ: " + event.values[2] + " rad/s"
                    + "X: " + event.values[3] + " rad/s \nY: " + event.values[4] + " rad/s \nZ: " + event.values[5] + " rad/s");
        }
        //else if (sm.getSensorList(Sensor.TYPE_STEP_COUNTER).size() != 0) { // MAY need a different process
        //    TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
        //    dynamictext.setText("X: " + event.values[0] + "\nY: " + event.values[1] + "\nZ: " + event.values[2]);
        //}
        //else if (sm.getSensorList(Sensor.TYPE_STEP_DETECTOR).size() != 0) { // Like sig, needs a different process
        //    TextView dynamictext = (TextView) findViewById(R.id.dynamictxt);
        //    dynamictext.setText("X: " + event.values[0] + "\nY: " + event.values[1] + "\nZ: " + event.values[2]);
        //}
    }


    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

class SenseThread extends Thread{
    Handler handler2;
    public SenseThread() {

    }

    public void run() {
        Looper.prepare();
        handler2=new Handler();
        Looper.loop();
    }
}

This flags up:

10-14 07:22:01.304    2333-2349/com.example.savag.babcockapplication E/SensorManager﹕ Exception dispatching input event.
    --------- beginning of crash
10-14 07:22:01.333    2333-2349/com.example.savag.babcockapplication E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-123
    Process: com.example.savag.babcockapplication, PID: 2333
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:907)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.view.View.requestLayout(View.java:18722)
            at android.widget.TextView.checkForRelayout(TextView.java:7172)
            at android.widget.TextView.setText(TextView.java:4342)
            at android.widget.TextView.setText(TextView.java:4199)
            at android.widget.TextView.setText(TextView.java:4174)
            at com.example.savag.babcockapplication.MainActivity.onSensorChanged(MainActivity.java:382)
            at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:481)
            at android.os.MessageQueue.nativePollOnce(Native Method)
            at android.os.MessageQueue.next(MessageQueue.java:323)
            at android.os.Looper.loop(Looper.java:135)
            at com.example.savag.babcockapplication.SenseThread.run(MainActivity.java:500)
10-14 07:22:03.691    2333-2350/com.example.savag.babcockapplication E/Surface﹕ getSlotFromBufferLocked: unknown buffer: 0xab97bd40
10-14 07:22:04.988    2333-2349/? I/Process﹕ Sending signal. PID: 2333 SIG: 9

So I know my problem I just don't know how to solve it.
And in actual fact this problem is three-fold.
First:
I've created a looper in the handler at the bottom tied to a looper, passed this handler into the registerlistener for my sensor. As you can see above, the error flags up "Only the original thread that created a view hierarchy can touch its views.". And this refers to the onSensorchanged for updating the dynamic text. How could I rectify this? I don't mind the dynamic text updating on the UIThread but in this case, sensorchanged would be tied to the new thread for the handling of the eventlisteners.

Second: The looper currently will run forever, how exactly do I stop and reuse the looper for the handler. Furthermore if I unregisterlistener will this automatically stop the running of the handler/looper for me? Documents everywhere tell me not to quit the looper and to just re-use but don't specify how to. Deleting and restarting the thread continuously is not an option either as this operation is expensive.

Thirdly:
Will this continuously update the sensor when changed or so I need to set-up a service coupled with an alarm? Slightly confused on the operation of this.

Please add me some clarification or suggestions. Thank you!

Savagefool
  • 223
  • 1
  • 4
  • 16
  • 1
    ad 2) use a `HandlerThread`, see [here](http://stackoverflow.com/a/25096981/2252830) on how to do that, and how to "talk" to a UI thread so you will fix your problem #1 – pskink Oct 14 '15 at 08:09
  • That worked perfectly, thank you! – Savagefool Oct 20 '15 at 08:49

0 Answers0