在这个android代码中找到错误

时间:2017-01-16 02:24:11

标签: android

应用程序在按下开始按钮时显示ANR(App Not Responding)对话框。 这个应用程序的动机是找到大约使用或电话行进的距离。我没有使用时钟,但只是检查应用程序是否正常工作 提前致谢

Java代码

    package com.skydiver.distancecalculator;
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    import java.util.Locale;

        public class MainActivity extends AppCompatActivity implements SensorEventListener {

    //Objects to access the sensors in the device
    Sensor accelero ;
    SensorManager manager;

    float currentAcc, lastAcc=0.0f, effectiveAcc;
    float distance = 0, totalDistance = 0;
    int time_elapsed = 0;

    //Text fields to show the value of acceleration,time and distance travelled
    TextView accX, accY, accZ, dist_total, dist_last, time;

    //Variables to store the value of acceleration in X,Y and Z directions
    public float val_accX, val_accY, val_accZ;

    //Buttons for starting and stopping the distance Calculations
    Button startButton, stopButton, resetButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Binding Button  in the java code with the layout widgets
        startButton = (Button) findViewById(R.id.start);
        stopButton = (Button) findViewById(R.id.stop);
        resetButton =(Button) findViewById(R.id.reset);

        //Getting the Sensor service using sensor manager object to access the accelerometer sensor in device
        manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        accelero = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        //Check if there is an accelerometer sensor present on the Device
        if(accelero == null){
            //Displays a message to the user that sensor is not present
            Toast.makeText(getApplicationContext(), "Sensor Not Present on Device", Toast.LENGTH_SHORT).show();
        }
        //Registering the sensor manager to listen to the sensor events at 10ms
        manager.registerListener(this, accelero, 10000);

        //Binding Textviews  in the java code with the layout widgets
        accX = (TextView) findViewById(R.id.text_accX);
        accY = (TextView) findViewById(R.id.text_accY);
        accZ = (TextView) findViewById(R.id.text_accZ);
        time = (TextView) findViewById(R.id.text_time);
        dist_last = (TextView) findViewById(R.id.text_last_dist);
        dist_total = (TextView) findViewById(R.id.text_total_dist);

        //Setting the function on click action of buttons
        resetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                resetFields();
            }
        });
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                resetFields();
                calculate();
            }
        });
        stopButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopCalculation();
            }
        });
    }

    @Override
    protected void onPause(){
        //Unregister the listener if the user moves to another activity or app
        manager.unregisterListener(this);
        super.onPause();
    }

    @Override
    protected void onResume(){
        //Resume the listener on resuming of the activity
        manager.registerListener(this,accelero, 10000);
        super.onResume();
    }

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        //Getting the changed values of the sensors in the variables
        val_accX = sensorEvent.values[0];
        val_accY = sensorEvent.values[1];
        val_accZ = sensorEvent.values[2];

        //Calling the function to calculate the total distance travelled
        calculate();
        //Display the current acceleration values to the user
        displayValues();

    }

    public void calculate() {

        while (true){
            currentAcc = (float) Math.sqrt(Math.pow(val_accZ,2)+Math.pow(val_accZ,2)+Math.pow(val_accZ,2) - Math.pow(9.80665,2));
            effectiveAcc = currentAcc - lastAcc;
            distance = Math.abs(effectiveAcc) * 0.5f * time_elapsed * time_elapsed ;
            totalDistance += distance;
            lastAcc = currentAcc;
            time_elapsed +=1;

            if (stopButton.isPressed()) {
                break;
            }
        }

    }

    private void stopCalculation(){
        dist_total.setText(String.format("Total Distance: " + "%s" + " m", Float.toString(totalDistance)));
        //time.setText(String.format(Locale.getDefault(),"Time: " + "%d" + " s", time_elapsed));
    }

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

    }

    public void resetFields(){
        time.setText(R.string.time_0_0);
        dist_last.setText(R.string.distance_0_0);
        dist_total.setText(R.string.total_distance_0_0);
    }

    public void displayValues(){
        accX.setText(String.format("Acceleration X: " + "%s" , val_accX));
        accY.setText(String.format("Acceleration Y: " + "%s" , val_accY));
        accZ.setText(String.format("Acceleration Z: " + "%s" , val_accZ));
    }
}


XML File
    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.skydiver.distancecalculator.MainActivity"
    android:orientation="vertical">


    <TextView
        android:text="@string/acceleration_x_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_accX" />

    <TextView
        android:text="@string/acceleration_y_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_accY" />

    <TextView
        android:text="@string/acceleration_z_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_accZ" />

    <TextView
        android:text="@string/time_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_time" />

    <TextView
        android:text="@string/distance_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_last_dist" />

    <TextView
        android:text="@string/total_distance_0_0"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:padding="3dp"
        android:layout_margin="3dp"
        android:gravity="start"
        android:layout_gravity="center_horizontal"
        android:id="@+id/text_total_dist" />

    <LinearLayout
        android:orientation="horizontal"
        android:layout_margin="5dp"
        android:padding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/start"
            android:text="@string/start"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp" />

        <Button
            android:id="@+id/stop"
            android:text="@string/stop"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp" />

    </LinearLayout>

    <Button
        android:id="@+id/reset"
        android:text="@string/reset_fields"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.skydiver.distancecalculator" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2 个答案:

答案 0 :(得分:1)

删除while (true) {行和相应的右括号。每次传感器更新时,您只需要循环内容执行一次。

同样删除这些行,因为只有当用户在执行时按下停止按钮时,此if语句才会为真:

 if (stopButton.isPressed()) {
     break;
 }

除非您在运行计算之外需要传感器值,否则应等到按下开始按钮后才能调用SensorManager.registerListener(),并且在按下停止按钮时应调用SensorManager.unregisterListener()(这就是为什么你不需要上面的if声明。否则,当您不需要传感器值并且运行加速度计时,您将接收传感器值。

答案 1 :(得分:0)

要扩展@ Karakuri的答案:传感器事件在主线程中进入。您打算快速处理它们并将控制权返回给操作系统。通过永久循环,您可以防止主线程做任何事情,包括响应Android生命周期事件,重绘或处理下一个传感器事件。你最终会被一个看门狗定时器杀死,它会查找UI线程卡住并杀死应用程序的情况。

您需要重新架构您的应用。没有循环。如果要停止响应事件,请从中取消注册。如果您想再次开始收听,请重新注册。