I have encounter some problem while trying to add buttons to my camera preview frame and i found out that when i add this line "setContentView(R.layout.main);" my program crashes. below is my code and my main.xml. Be note that the xml is default generated and nothing had been modified.
My Code
package camera.test;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainActivity extends Activity
{
Camera mCamera;
private Preview mPreview;
private DrawOnTop mDraw;
private CameraConfigurationManager manager;
Display display;
public static Point screenResolution, cameraResolution;
private Rect framingRect;
private Rect framingRectInPreview;
private Rect rect;
private Camera.Parameters params;
private Context mContext;
public static String flag;
private static final int MIN_FRAME_WIDTH = 240;
private static final int MAX_FRAME_WIDTH = 300;
private static final int MIN_FRAME_HEIGHT = 240;
private static final int MAX_FRAME_HEIGHT = 200;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.main); //if i add this line the app will crash
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//params = Camera.getParameters();
mContext = this;
mPreview = new Preview(this);
setContentView(mPreview);
manager = new CameraConfigurationManager(this);
Display display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
screenResolution = new Point(display.getWidth(), display.getHeight());
//cameraResolution = manager.getCameraResolution(params, screenResolution);
rect = getFramingRect();
mDraw = new DrawOnTop(this, rect);
addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
//mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
public void onResume() {
super.onResume();
mCamera = Camera.open();
mPreview.setCamera(mCamera);
}
public void onPause() {
super.onPause();
if(mCamera != null) {
mPreview.setCamera(null);
mCamera.release();
mCamera = null;
}
}
public static int leftOffset;
public Rect getFramingRect() {
if (framingRect == null) {
if (mCamera == null) {
flag = "its null";
//return null;
}
//Point screenResolution = manager.getScreenResolution();
int width = screenResolution.x *3/4;
if (width < MIN_FRAME_WIDTH) {
width = MIN_FRAME_WIDTH;
} else if (width > MAX_FRAME_WIDTH) {
width = MAX_FRAME_WIDTH;
}
int height = screenResolution.y * 3 / 4;
if (height < MIN_FRAME_HEIGHT) {
height = MIN_FRAME_HEIGHT;
} else if (height > MAX_FRAME_HEIGHT) {
height = MAX_FRAME_HEIGHT;
}
leftOffset = (screenResolution.x - width) / 2;
int topOffset = (screenResolution.y - height) / 2;
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
flag = framingRect.bottom+"";
//Log.d(TAG, "Calculated framing rect: " + framingRect);*/
}
return framingRect;
}
public Rect getFramingrectInPreview() { //from zxing
if(framingRectInPreview == null) {
Rect rect = new Rect(getFramingRect());
//Point p = manager.getCameraResolution();
//Point p2 = manager.getScreenResolution();
rect.left = rect.left * cameraResolution.x / screenResolution.x;
rect.right = rect.right * cameraResolution.x / screenResolution.x;
rect.top = rect.top * cameraResolution.y / screenResolution.y;
rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
framingRectInPreview = rect;
}
return framingRectInPreview;
}
}
class DrawOnTop extends View {
//CameraConfigurationManager manager;
private Rect rect;
public DrawOnTop(Context context, Rect rect1) {
super(context);
//manager = new CameraConfigurationManager(context);
rect = rect1;
}
protected void onDraw(Canvas canvas) {
//Rect rect = getFramingRect();
//Point tt = manager.getCameraResolution();
//int k = tt.y;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setAlpha(100);
canvas.drawRect(0, 0, rect.left, MainActivity.screenResolution.y, paint);
canvas.drawRect(rect.right, 0, MainActivity.screenResolution.x, MainActivity.screenResolution.y, paint);
canvas.drawRect(rect.left, 0, rect.right, rect.top, paint);
canvas.drawRect(rect.left, rect.bottom, rect.right, MainActivity.screenResolution.y, paint);
//paint.setAlpha(255);
canvas.drawText(Preview.test1+"", 100, 100, paint);
//canvas.drawRect(rect, paint);
//canvas.drawPoint(rect.top, rect.left, paint);
//canvas.drawCircle(rect.right,0, 10, paint);
//canvas.drawRect(rect, paint);
//canvas.drawColor(Color.GRAY);
//paint.setAlpha(255);
//canvas.drawCircle(10, 10, 10, paint);
super.onDraw(canvas);
}
}
class Preview extends ViewGroup implements SurfaceHolder.Callback {
private final String TAG = "Preview";
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;
public static int test1, test2;
//Display display;
Preview(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
}
public void setCamera(Camera camera) {
mCamera = camera;
if(mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
requestLayout();
}
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if(mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if(mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
if(width*previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) /2, 0, (width + scaledChildWidth) /2, height);
}
else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height-scaledChildHeight) / 2, width, (height + scaledChildHeight) /2);
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
try {
if(mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
}
catch (IOException exception) {
}
}
Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
test1 = 8889898;
//throw new UnsupportedOperationException("Not supported yet.");
int ARRAY_LENGTH = mPreviewSize.width*mPreviewSize.height*3/2;
int argb8888[] = new int[ARRAY_LENGTH];
decodeYUV(argb8888, data, mPreviewSize.width, mPreviewSize.height);
Bitmap bitmap = Bitmap.createBitmap(argb8888, mPreviewSize.width, mPreviewSize.height, Config.ARGB_8888);
FileOutputStream fos;
try {
fos = new FileOutputStream(String.format("/sdcard/testImage/%d.jpg", System.currentTimeMillis()));
BufferedOutputStream bos = new BufferedOutputStream(fos);
bitmap.compress(CompressFormat.JPEG, 75, bos);
bos.flush();
bos.close();
fos.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(Preview.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
// decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android
// David Manpearl 081201
public void decodeYUV(int[] out, byte[] fg, int width, int height)
throws NullPointerException, IllegalArgumentException {
int sz = width * height;
if (out == null)
throw new NullPointerException("buffer out is null");
if (out.length < sz)
throw new IllegalArgumentException("buffer out size " + out.length
+ " < minimum " + sz);
if (fg == null)
throw new NullPointerException("buffer 'fg' is null");
if (fg.length < sz)
throw new IllegalArgumentException("buffer fg size " + fg.length
+ " < minimum " + sz * 3 / 2);
int i, j;
int Y, Cr = 0, Cb = 0;
for (j = 0; j < height; j++) {
int pixPtr = j * width;
final int jDiv2 = j >> 1;
for (i = 0; i < width; i++) {
Y = fg[pixPtr];
if (Y < 0)
Y += 255;
if ((i & 0x1) != 1) {
final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
Cb = fg[cOff];
if (Cb < 0)
Cb += 127;
else
Cb -= 128;
Cr = fg[cOff + 1];
if (Cr < 0)
Cr += 127;
else
Cr -= 128;
}
int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if (R < 0)
R = 0;
else if (R > 255)
R = 255;
int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1)
+ (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if (G < 0)
G = 0;
else if (G > 255)
G = 255;
int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if (B < 0)
B = 0;
else if (B > 255)
B = 255;
out[pixPtr++] = 0xff000000 + (B << 16) + (G << 8) + R;
}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
//mCamera.setPreviewCallback(null);
if(mCamera != null) {
mCamera.stopPreview();
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double)w/h;
if(sizes==null) {
return null;
}
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for(Size size : sizes) {
double ratio = (double) size.width / size.height;
if(Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if(Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if(optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if(Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
//mCamera.setDisplayOrientation(90);
requestLayout();
mCamera.setPreviewCallback(mPreviewCallback);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
public Camera.Size getBestPreviewSize(Camera.Parameters parameters, int w, int h)
{
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes())
{
if (size.width <= w && size.height <= h)
{
if (null == result)
result = size;
else
{
int resultDelta = w - result.width + h - result.height;
int newDelta = w - size.width + h - size.height;
if (newDelta < resultDelta)
result = size;
}
}
}
return result;
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<SurfaceView android:id="@+id/surface_camera"
android:layout_width="fill_parent" android:layout_height="10dip"
android:layout_weight="1">
</SurfaceView>
</LinearLayout>
Logcat error:
08-15 14:05:14.897: ERROR/AndroidRuntime(450): FATAL EXCEPTION: main
08-15 14:05:14.897: ERROR/AndroidRuntime(450): FATAL EXCEPTION: main
08-15 14:05:14.897: ERROR/AndroidRuntime(450): java.lang.RuntimeException: Unable to start activity ComponentInfo{camera.test/camera.test.MainActivity}: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.os.Handler.dispatchMessage(Handler.java:99)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.os.Looper.loop(Looper.java:123)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at java.lang.reflect.Method.invokeNative(Native Method)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at java.lang.reflect.Method.invoke(Method.java:507)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at dalvik.system.NativeStart.main(Native Method)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
08-15 14:05:14.开发者_运维问答897: ERROR/AndroidRuntime(450): at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.Activity.requestWindowFeature(Activity.java:2729)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at camera.test.MainActivity.onCreate(MainActivity.java:67)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-15 14:05:14.897: ERROR/AndroidRuntime(450): ... 11 more
08-15 14:05:14.917: WARN/ActivityManager(109): Force finishing activity camera.test/.MainActivity
You are getting your error on
requestWindowFeature(Window.FEATURE_NO_TITLE);
It's much simpler to declare an activity as having no title in the manifest by having the title be empty.
Take a look at this document and you might be able to understand how this works a bit better.
Good luck!
The error you got is due to this line:
requestWindowFeature(Window.FEATURE_NO_TITLE);
It has to be called just after the call to the parent method. In your case, you won't have any crash with that order:
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
精彩评论