下面是一个使用Android AR Sceneform库的示例代码,用于检测设备方向变化:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.filament.Engine;
import com.google.ar.core.Anchor;
import com.google.ar.core.ArCoreApk;
import com.google.ar.core.ArSession;
import com.google.ar.core.Camera;
import com.google.ar.core.Frame;
import com.google.ar.core.Plane;
import com.google.ar.core.Pose;
import com.google.ar.core.Session;
import com.google.ar.core.TrackingState;
import com.google.ar.sceneform.AnchorNode;
import com.google.ar.sceneform.ArSceneView;
import com.google.ar.sceneform.Node;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.rendering.Renderable;
import com.google.ar.sceneform.ux.ArFragment;
import com.google.ar.sceneform.ux.TransformableNode;
import java.util.List;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private static final String TAG = MainActivity.class.getSimpleName();
private ArFragment arFragment;
private ArSceneView arSceneView;
private ModelRenderable modelRenderable;
private SensorManager sensorManager;
private Sensor accelerometerSensor;
private Sensor magnetometerSensor;
private float[] accelerometerData = new float[3];
private float[] magnetometerData = new float[3];
private float[] rotationMatrix = new float[9];
private float[] orientationAngles = new float[3];
private boolean isTracking = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
arSceneView = arFragment.getArSceneView();
// 加载和渲染3D模型
ModelRenderable.builder()
.setSource(this, R.raw.model)
.build()
.thenAccept(renderable -> modelRenderable = renderable)
.exceptionally(throwable -> {
Log.e(TAG, "Unable to load renderable", throwable);
return null;
});
// 初始化传感器
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
@Override
protected void onResume() {
super.onResume();
if (arSceneView.getSession() == null) {
try {
// 检查ARCore是否支持当前设备
ArCoreApk.InstallStatus installStatus = ArCoreApk.getInstance().requestInstall(this, true);
if (installStatus == ArCoreApk.InstallStatus.INSTALLED) {
// 创建AR会话
ArSession arSession = new ArSession(this);
arSceneView.setupSession(arSession);
}
} catch (Exception e) {
Log.e(TAG, "Error creating AR session", e);
}
}
// 注册传感器监听器
sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, magnetometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
// 开始渲染AR场景
arSceneView.resume();
}
@Override
protected void onPause() {
super.onPause();
// 注销传感器监听器
sensorManager.unregisterListener(this, accelerometerSensor);
sensorManager.unregisterListener(this, magnetometerSensor);
// 暂停渲染AR场景
arSceneView.pause();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, accelerometerData, 0, accelerometerData.length);
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, magnetometerData, 0, magnetometerData.length);
}
// 计算设备的方向
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerData, magnetometerData);
SensorManager.getOrientation(rotationMatrix, orientationAngles);
// 更新AR场景中的3D模型方向
if (modelRenderable != null && isTracking) {
arSceneView.get