我一直在搜索和编码这个问题3天,没有结果:(
我制作了一个代码在这里的相机覆盖图+加速度计
public class CameraActivity extends Activity implements SurfaceHolder.Callback, SensorEventListener {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
static String TAG = CameraActivity.class.getSimpleName();
// Accelerometer
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.surface_view);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.camera_control,
null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(viewControl, layoutParamsControl);
// Accelerometer
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
然后在camera_control.xml中我有这个:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_holder"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/transparent"
android:gravity="bottom" >
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/camera_red_button"
android:layout_alignLeft="@+id/camera_back_button"
android:layout_marginBottom="27dp"
android:src="@drawable/camera_accelerometer_red" />
</RelativeLayout>
并在surface_view.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camerapreview_holder"
>
<SurfaceView
android:id="@+id/camerapreview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
图像视图是精神层面的图像。
这个想法是用户在拍摄照片之前需要调平相机。我已经清除了所有不需要的代码。上面的代码是工作代码。
问题: 我需要为精神层面制造一个球。它不需要是最平滑的精神层面。如果我能找到将球限制在精神层面并根据加速度计结果移动它的方法,我会像拉里一样快乐:)/
如果有人请我就这三件事指出正确的方向:
提前致谢。 小时。
答案 0 :(得分:1)
好的我已经得到了答案。希望它可以帮助某人。您需要使用计算从中间到角落的距离(半径)偏移角落。
此外,我已将Accelerometor更改为方向传感器,然后我可以在X和Y轴上获得手机的3D旋转。
以下代码是工作代码,我测试了它们。我使用的是Android 2.3.3+ 球的运动不是很平滑,因为这不是应用的目的。
我认为为了平滑移动,您可能还需要添加计时器和碰撞检测。请检查android示例。
我还没有重构代码。所以这不是生产级代码:)
代码:
public class CameraActivity extends Activity implements SurfaceHolder.Callback,
SensorEventListener {
// Accelerometer
private SensorManager mSensorManager;
private Sensor mAccelerometer;
/** Called when the activity is first created. */
public static float x;
public static float y;
FrameLayout layout_holder;
FrameLayout ball_holder;
// private float hOriginSize;
float halfOfWidth;
int centerYOnImage;
private Sensor mOrientation;
// float viewInset = 14.0f; // I remove this simply to make the code cleaner. I used this to calculate the radius and the offset later on
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.surface_view);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.camera_control,
null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.addContentView(viewControl, layoutParamsControl);
// Accelerometer
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ball);
CustomDrawableView mCustomDrawableView = new CustomDrawableView(this,
bitmap);
ball_holder = (FrameLayout) findViewById(R.id.ball_holder);
ball_holder.addView(mCustomDrawableView);
halfOfWidth = 40; // You can calculate this, I just put this so I can test it. This is the half of the width of target image - attached in the question
centerYOnImage = 40; // Not important :)
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
// This method will update the UI on new sensor events
public void onSensorChanged(SensorEvent event) {
// float azimuth_angle = event.values[0];
x = event.values[1];
y = event.values[2];
// FIXME: Fine tune this for the image taking part
float ratio = 70.0f / 25.0f;
x = x * ratio;
y = y * ratio;
Log.d(TAG, "x and y: " + x + " " + y);
float maxDistance = 35; // To calculate this halfOfWidth - viewInset;
// to calculate between 2 distances
float distance = (float) Math.sqrt(((x) * (x)) + ((y) * (y)));
if (distance > maxDistance) {
float angle = (float) Math.atan2(x, y);
/ Get new point on the edge of the circle
y = (float) (Math.cos(angle) * maxDistance);
x = (float) (Math.sin(angle) * maxDistance);
}
x = x + 40; // 40 is the half od the distance of the full width
y = (y * -1.0f) + 40; // -1.0f is so orientation works like the actual spirit level
canUserTakePhoto(distance);
}
// Change the background
public void canUserTakePhoto(float treshold) {
if (treshold > 10) {
// Not Yet
} else {
// take it
}
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mOrientation,
SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public class CustomDrawableView extends ImageView {
Bitmap b;
public CustomDrawableView(Context context, Bitmap bitmap) {
super(context);
this.b = bitmap;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(this.b, x, y, null);
invalidate();
}
}
@Override
public void onDestroy() // main thread stopped
{
super.onDestroy();
// wait for threads to exit before clearing app
System.runFinalizersOnExit(true);
// remove app from memory
android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
干杯。