Я новичок в Android Studio и не понимаю, почему метод onSensorChanged()
не выдает ошибок и предупреждений, а возвращает ноль. Я хочу «накатить мяч на экран устройства». Графический компонент работает хорошо. Я вижу шар с постоянной скоростью движения, и я хочу отрегулировать скорость, умножив его на угол экрана, и поэтому моя скорость становится равной нулю. Пожалуйста, помогите мне исправить это.
Я тестирую приложение на реальном устройстве Xiaomi MI9 SE.
//MAIN ACTIVITY
package com.example.app_2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class Gravity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_gravity);
setContentView(new MovementView(this));
}
}
//PHYSICS
package com.example.app_2;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MovementView extends SurfaceView implements SurfaceHolder.Callback {
public float xPos;
public float yPos;
public float xVel;
public float yVel;
public float width;
public float height;
private float circleRadius;
private Paint circlePaint;
UpdateThread updateThread;
public MovementView(Context context) {
super(context);
getHolder().addCallback(this);
circleRadius = 30;
circlePaint = new Paint();
circlePaint.setColor(Color.RED);
xVel = 2 ; // скорость движения
yVel = 2 ; // шарика
}
@Override
public void onDraw(Canvas c) {
c.drawColor(Color.WHITE);
c.drawCircle(xPos, yPos, circleRadius, circlePaint);
}
public void updatePhysics() {
float xz, zy;
xz = Acceleration.Accel(1);
zy = Acceleration.Accel(-1);
xPos += xVel - xz;
yPos += yVel - zy;
if (yPos - circleRadius < 0 || yPos + circleRadius > height) {
//В случае ударов о верх или низ холста
if (yPos - circleRadius < 0) {
//Удар о верхнюю грань
yPos = circleRadius;
}else{
//Удар о нижнюю грань
yPos = height - circleRadius;
}
//Меняем направление шарика
yVel *= -1;
}
if (xPos - circleRadius < 0 || xPos + circleRadius > width) {
//В случае столкновений с правой или левой стенками
if (xPos - circleRadius < 0) {
//В случае столкновений с левой стенкой
xPos = circleRadius;
} else {
//В случае столкновений с правой стенкой
xPos = width - circleRadius;
}
//Меняем x направление на обратное
xVel *= -1;
}
}
public void surfaceCreated(SurfaceHolder holder) {
Rect surfaceFrame = holder.getSurfaceFrame();
width = surfaceFrame.width();
height = surfaceFrame.height();
xPos = width / 2;
yPos = height / 2;
updateThread = new UpdateThread(this);
updateThread.setRunning(true);
updateThread.start();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
updateThread.setRunning(false);
while (retry) {
try {
updateThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
//THREAD
package com.example.app_2;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class UpdateThread extends Thread{
private long time;
private final int fps = 5;
private boolean toRun = false;
private MovementView movementView;
private SurfaceHolder surfaceHolder;
UpdateThread(MovementView rMovementView) {
movementView = rMovementView;
surfaceHolder = movementView.getHolder();
}
void setRunning(boolean run) {
toRun = run;
}
@Override
public void run() {
Canvas c;
while (toRun) {
long cTime = System.currentTimeMillis();
//if ((cTime - time) <= (100000 / fps)) {
c = null;
try {
c = surfaceHolder.lockCanvas(null);
movementView.updatePhysics();
movementView.onDraw(c);
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
//}
time = cTime;
}
}
}
//ACCELERATION
package com.example.app_2;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import androidx.core.content.ContextCompat;
import static android.content.Context.SENSOR_SERVICE;
import static android.hardware.Sensor.TYPE_ROTATION_VECTOR;
import static androidx.core.content.ContextCompat.getSystemService;
public class Acceleration extends Service implements SensorEventListener {
public SensorManager sensorManager;
public static float xy_angle, xz_angle, zy_angle;
public Acceleration(Context pContext) {
sensorManager = (SensorManager) pContext.getSystemService(SENSOR_SERVICE);
assert sensorManager != null;
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(TYPE_ROTATION_VECTOR),
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
assert sensorManager != null;
xy_angle = sensorEvent.values[0];
xz_angle = sensorEvent.values[1];
zy_angle = sensorEvent.values[2];
}
public static float Accel(int a){
float angle;
if (a > 0){
angle = xz_angle;
} else {
angle = zy_angle;
}
return angle;
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Я ожидаю, что Acceleration.Accel(1)
вернет значение датчика TYPE_ROTATION_VECTOR
во время запроса данных, но я всегда получаю ноль.