android - puedo - plantilla de curriculum vitae para movil
La cámara personalizada de Android se bloquea en el curriculum vitae (3)
Tengo esta actividad de cámara personalizada en mi aplicación, que está funcionando bien, pero cuando presiono el botón de inicio mientras estoy en la cámara, y luego regreso a la aplicación, falla, y el logcat dice que hubo una excepción de puntero nulo en el creación de vista de superficie. Este método de instalación se llama onResume:
public void setup()
{
preview = new CameraPreview(this);
((FrameLayout) findViewById(R.id.camera_preview)).addView(preview);
head=(ImageView)findViewById(R.id.head);
head.setX((float)(Shared.screenWidth/5*1.8));
head.setY((float)(Shared.screenHeight*0.03));
LayoutParams params = (LayoutParams) head.getLayoutParams();
params.width = (int)((Shared.screenWidth/5*3.2)-(head.getX()));
params.height=(int)((Shared.screenHeight/3.8)-(head.getY()));
head.setLayoutParams(params);
body=(ImageView)findViewById(R.id.body);
body.setX((float)(Shared.screenWidth/7));
body.setY((float)(Shared.screenHeight/3.8));
LayoutParams params2 = (LayoutParams) body.getLayoutParams();
params2.width = (int)((Shared.screenWidth/7*6)-(body.getX()));
params2.height=(int)((Shared.screenHeight)-(body.getY()));
body.setLayoutParams(params2);
go=(Button)findViewById(R.id.go);
again=(Button)findViewById(R.id.again);
stop=(ImageButton)findViewById(R.id.stop);
stop.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Intent i =new Intent(CamActivity.this,Main.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
btn = (ImageButton) findViewById(R.id.takePic);
btn.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
btn.setVisibility(View.INVISIBLE);
btn.setEnabled(false);
go.setVisibility(View.VISIBLE);
go.setEnabled(true);
head.setVisibility(View.INVISIBLE);
body.setVisibility(View.INVISIBLE);
go.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Shared.bm=Bitmap.createScaledBitmap(bmp, Shared.screenWidth, Shared.screenHeight, true);
Intent i=new Intent(CamActivity.this,IKill.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
again.setVisibility(View.VISIBLE);
again.setEnabled(true);
again.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 11) {
recreate();
} else {
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
}
});
}
});
}
Además, en mi método onCreate también tengo esto:
requestWindowFeature(Window.FEATURE_NO_TITLE);
// hide status bar
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera);
y el logcat:
08-23 08:56:20.174: E/AndroidRuntime(835): FATAL EXCEPTION: main
08-23 08:56:20.174: E/AndroidRuntime(835): java.lang.NullPointerException
08-23 08:56:20.174: E/AndroidRuntime(835): at
com.example.i_kill.CameraPreview.surfaceCreated(CameraPreview.java:38)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.SurfaceView.updateWindow(SurfaceView.java:569)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.SurfaceView.access$000(SurfaceView.java:86)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.SurfaceView$3.onPreDraw(SurfaceView.java:174)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1842)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.Choreographer.doCallbacks(Choreographer.java:562)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.Choreographer.doFrame(Choreographer.java:532)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.os.Handler.handleCallback(Handler.java:725)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.os.Handler.dispatchMessage(Handler.java:92)
08-23 08:56:20.174: E/AndroidRuntime(835): at android.os.Looper.loop(Looper.java:137)
08-23 08:56:20.174: E/AndroidRuntime(835): at
android.app.ActivityThread.main(ActivityThread.java:5041)
08-23 08:56:20.174: E/AndroidRuntime(835): at
java.lang.reflect.Method.invokeNative(Native Method)
08-23 08:56:20.174: E/AndroidRuntime(835): at
java.lang.reflect.Method.invoke(Method.java:511)
08-23 08:56:20.174: E/AndroidRuntime(835): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-23 08:56:20.174: E/AndroidRuntime(835): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-23 08:56:20.174: E/AndroidRuntime(835): at dalvik.system.NativeStart.main(Native
Method)
08-23 08:56:26.065: E/Trace(909): error opening trace file: No such file or directory
y aquí está toda la clase: package com.example.i_kill;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
public class CamActivity extends Activity {
public static final int MEDIA_TYPE_IMAGE = 1;
public static String TAG="MainActivity";
private static Camera camera;
private CameraPreview preview;
private ImageView head,body;
private ImageButton btn, stop;
private Button again,go;
private Bitmap bmp;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// hide status bar
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera);
}
public void setup()
{
preview = new CameraPreview(this);
((FrameLayout) findViewById(R.id.camera_preview)).addView(preview);
head=(ImageView)findViewById(R.id.head);
head.setX((float)(Shared.screenWidth/5*1.8));
head.setY((float)(Shared.screenHeight*0.03));
LayoutParams params = (LayoutParams) head.getLayoutParams();
params.width = (int)((Shared.screenWidth/5*3.2)-(head.getX()));
params.height=(int)((Shared.screenHeight/3.8)-(head.getY()));
head.setLayoutParams(params);
body=(ImageView)findViewById(R.id.body);
body.setX((float)(Shared.screenWidth/7));
body.setY((float)(Shared.screenHeight/3.8));
LayoutParams params2 = (LayoutParams) body.getLayoutParams();
params2.width = (int)((Shared.screenWidth/7*6)-(body.getX()));
params2.height=(int)((Shared.screenHeight)-(body.getY()));
body.setLayoutParams(params2);
go=(Button)findViewById(R.id.go);
again=(Button)findViewById(R.id.again);
stop=(ImageButton)findViewById(R.id.stop);
stop.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Intent i =new Intent(CamActivity.this,Main.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
btn = (ImageButton) findViewById(R.id.takePic);
btn.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);
btn.setVisibility(View.INVISIBLE);
btn.setEnabled(false);
go.setVisibility(View.VISIBLE);
go.setEnabled(true);
head.setVisibility(View.INVISIBLE);
body.setVisibility(View.INVISIBLE);
go.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
Shared.bm=Bitmap.createScaledBitmap(bmp, Shared.screenWidth, Shared.screenHeight, true);
Intent i=new Intent(CamActivity.this,IKill.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
});
again.setVisibility(View.VISIBLE);
again.setEnabled(true);
again.setOnClickListener( new OnClickListener() {
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 11) {
recreate();
} else {
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
}
});
}
});
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter''d");
}
};
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
bmp=BitmapFactory.decodeByteArray(data, 0, data.length );
System.out.println(bmp.getHeight());
System.out.println(bmp.getWidth());
};
};
public void onPause(){
super.onPause();
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
public void onResume()
{
super.onResume();
setup();
}
}
y clase de vista previa de la cámara:
package com.example.i_kill;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
public Camera camera;
public static String TAG="CameraPreview";
public CameraPreview(Context context) {
super(context);
holder=getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
camera = getCameraInstance();
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
CameraPreview.this.invalidate();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
List<Size> previewSizes = parameters.getSupportedPreviewSizes();
Size bestSize = null;
int bestDiff = 0;
int diff = 0;
for (Size size : previewSizes) {
diff = Math.abs(h - size.height) + Math.abs(w - size.width);
if (bestSize == null || diff < bestDiff) {
bestSize = size;
bestDiff = diff;
}
parameters.setPreviewSize(bestSize.width, bestSize.height);
camera.setParameters(parameters);
}
//start preview of camera
camera.startPreview();
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p= new Paint(Color.RED);
Log.d(TAG,"draw");
canvas.drawText("PREVIEW", canvas.getWidth()/2, canvas.getHeight()/2, p );
}
private Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
}
Gracias por tu ayuda :)
¿No debería hacerse la llamada a getHolder () en surfaceCreated? Encontré lo siguiente en la documentación :
El acceso a la superficie subyacente se proporciona a través de la interfaz SurfaceHolder, que se puede recuperar llamando a getHolder ().
La superficie se creará para usted mientras la ventana de SurfaceView esté visible; debe implementar surfaceCreated (SurfaceHolder) y surfaceDestroyed (SurfaceHolder) para descubrir cuándo se crea y se destruye la superficie, ya que la ventana se muestra y se oculta.
Esta es mi solución.
public void onResume(){
super.onResume();
if(mCamera ==null){
setContentView(R.layout.activity_capture_local_plates);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
}
}
Lo resolví llamando a setContentView
en el currículum. ¡Gracias a todos!