我一直在使用这个Android应用程序(不是我的代码)现在我刚刚发现了一个问题,我正在拍照。 "它在三星Note 10.1平板电脑上运行良好"但是当我在手机中试用它时,应用会在我拍照时停止。我已经在这里停留了几天,现在正在寻找解决方案,而且我不知道在哪里可以追踪问题了。
我调试了程序,发现图像为空。但数据有价值。这是我发现问题的代码
private Camera.PictureCallback takePictureCallback = new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG,"takePictureCallback.onPictureTaken");
Bitmap image = processImage(data);
if(mTakePictureListener!=null){
mTakePictureListener.onTakePicture(image);
}
}
};
我很抱歉这令人困惑,因为我无法很好地解释细节。我真的很感激一些帮助。如果你愿意,你可以向我询问更多信息。
这是logcat
10-27 09:02:22.593 1664-1664/com.project.app V/CameraPreview﹕ preview started
10-27 09:02:22.593 1664-1664/com.project.app V/CameraPreview﹕ SurfaceChanged finished
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: left = 0
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: left = 0
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: top = 0
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: right = 480`
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: bottom = 24
10-27 09:02:31.121 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: mProgressDrawable.setBounds()
10-27 09:02:31.431 1664-1664/com.project.app V/CameraPreview﹕ postPreview.onPictureTaken
10-27 09:02:31.461 1664-1664/com.project.app D/skia﹕ --- SkImageDecoder::Factory returned null
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ java.lang.NullPointerException
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview.processImage(CameraPreview.java:90)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview.access$200(CameraPreview.java:27)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview$3.onPictureTaken(CameraPreview.java:65)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:99)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at android.os.Looper.loop(Looper.java:176)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5317)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
10-27 09:02:31.461 1664-1664/com.project.app W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
10-27 09:02:31.471 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: left = 0
10-27 09:02:31.471 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: top = 0
10-27 09:02:31.471 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: right = 480
10-27 09:02:31.471 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: bottom = 0
10-27 09:02:31.471 1664-1664/com.project.app D/ProgressBar﹕ updateDrawableBounds: mProgressDrawable.setBounds()
10-27 09:02:31.852 1664-1664/com.project.app V/CameraPreview﹕ takePictureCallback.onPictureTaken
10-27 09:02:31.902 1664-1664/com.project.app I/dalvikvm-heap﹕ Grow heap (frag case) to 36.449MB for 19660816-byte allocation
10-27 09:02:31.932 1664-1673/com.project.app D/dalvikvm﹕ GC_FOR_ALLOC freed 70K, 13% free 36412K/41608K, paused 37ms, total 37ms
10-27 09:02:31.952 1664-1673/com.project.app D/AbsListView﹕ [unregisterDoubleTapMotionListener]
10-27 09:02:31.952 1664-1673/com.project.app I/MotionRecognitionManager﹕ .unregisterListener : / listener count = 0->0,
10-27 09:02:31.952 1664-1673/com.project.app D/AbsListView﹕ unregisterIRListener() is called
10-27 09:02:31.952 1664-1673/com.project.app D/AbsListView﹕ [unregisterDoubleTapMotionListener]
10-27 09:02:31.952 1664-1673/com.project.app I/MotionRecognitionManager﹕ .unregisterListener : / listener count = 0->0,
10-27 09:02:31.952 1664-1673/com.project.app D/AbsListView﹕ unregisterIRListener() is called
10-27 09:02:31.972 1664-1668/com.project.app E/dalvikvm﹕ adjustAdaptiveCoef max=4194304, min=1048576, ut=568
10-27 09:02:31.972 1664-1668/com.project.app D/dalvikvm﹕ GC_CONCURRENT freed 790K, 15% free 35625K/41608K, paused 4ms+3ms, total 41ms
10-27 09:02:32.242 1664-1664/com.project.app D/dalvikvm﹕ GC_FOR_ALLOC freed 4325K, 25% free 31300K/41608K, paused 24ms, total 24ms
10-27 09:02:32.242 1664-1664/com.project.app I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 14745616-byte allocation
10-27 09:02:32.272 1664-1664/com.project.app D/dalvikvm﹕ GC_BEFORE_OOM freed 11K, 25% free 31289K/41608K, paused 30ms, total 30ms
10-27 09:02:32.272 1664-1664/com.project.app E/dalvikvm-heap﹕ Out of memory on a 14745616-byte allocation.
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ "main" prio=5 tid=1 RUNNABLE
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x419199a0 self=0x41909300
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ | sysTid=1664 nice=0 sched=0/0 cgrp=apps handle=1075561948
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ | state=R schedstat=( 0 0 0 ) utm=1561 stm=218 core=0
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.graphics.Bitmap.nativeCreate(Native Method)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:718)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:695)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:628)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at capture.CameraPreview.processImage(CameraPreview.java:94)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at capture.CameraPreview.access$200(CameraPreview.java:27)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at capture.CameraPreview$2.onPictureTaken(CameraPreview.java:51)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.hardware.Camera$EventHandler.handleMessage(Camera.java:846)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.os.Handler.dispatchMessage(Handler.java:99)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.os.Looper.loop(Looper.java:176)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at android.app.ActivityThread.main(ActivityThread.java:5317)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at java.lang.reflect.Method.invokeNative(Native Method)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at java.lang.reflect.Method.invoke(Method.java:511)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ at dalvik.system.NativeStart.main(Native Method)
10-27 09:02:32.282 1664-1664/com.project.app I/dalvikvm﹕ [ 10-27 09:02:32.282 1664: 1664 W/System.err ]
java.lang.OutOfMemoryError
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.graphics.Bitmap.nativeCreate(Native Method)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:718)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:695)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.graphics.Bitmap.createBitmap(Bitmap.java:628)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview.processImage(CameraPreview.java:94)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview.access$200(CameraPreview.java:27)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at capture.CameraPreview$2.onPictureTaken(CameraPreview.java:51)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.hardware.Camera$EventHandler.handleMessage(Camera.java:846)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:99)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.os.Looper.loop(Looper.java:176)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5317)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
10-27 09:02:32.282 1664-1664/com.project.app W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
10-27 09:02:32.292 1664-1664/com.project.app D/AndroidRuntime﹕ Shutting down VM
10-27 09:02:32.292 1664-1664/com.project.app W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41918930)
10-27 09:02:32.332 1664-1664/com.project.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at capture.CaptureFragment.bitmapToFile(CaptureFragment.java:544)
at capture.CaptureFragment.access$100(CaptureFragment.java:65)
at capture.CaptureFragment$2.onTakePicture(CaptureFragment.java:117)
at capture.CameraPreview$2.onPictureTaken(CameraPreview.java:54)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:846)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5317)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
以下是CameraPreview的代码
private AutoFocusCallback onFocus = new AutoFocusCallback(){
@Override
public void onAutoFocus(boolean success, Camera camera) {
justTakeTheDamPicture();
}
};
private Camera.PictureCallback takePictureCallback = new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG,"takePictureCallback.onPictureTaken");
Bitmap image = processImage(data);
if(mTakePictureListener!=null){
mTakePictureListener.onTakePicture(image);
}
}
};
private Camera.PictureCallback postPreviewCallback = new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.v(TAG,"postPreview.onPictureTaken");
if(data!=null){
Bitmap image = processImage(data);
if(mTakePictureListener!=null){
mTakePictureListener.onPostPreview(image);
}
}
}
};
private Bitmap processImage(byte[] data){
try{
Options options = new Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length, options);
long currTime = System.currentTimeMillis();
Bitmap croppedImage = null;
Bitmap resizedImage = null;
Matrix matrix = new Matrix();
matrix.postRotate(90);
if(image.getHeight()>image.getWidth()){
croppedImage = Bitmap.createBitmap(image, 0,(image.getHeight()/2)-(image.getWidth()/2),image.getWidth(), image.getWidth(),matrix,false);
resizedImage = Bitmap.createScaledBitmap(croppedImage, IMAGE_WIDTH, IMAGE_WIDTH, false);
}else{
croppedImage = Bitmap.createBitmap(image, (image.getWidth()/2)-(image.getHeight()/2),0,image.getHeight(), image.getHeight(),matrix,false);
resizedImage = Bitmap.createScaledBitmap(croppedImage, IMAGE_WIDTH, IMAGE_WIDTH, false);
}
long croppingTime = System.currentTimeMillis() - currTime;
Log.v(TAG,"Cropping time: "+croppingTime);
return resizedImage;
}catch(OutOfMemoryError e){
e.printStackTrace();
Toast.makeText(getContext(),R.string.out_of_memory, Toast.LENGTH_LONG);
return null;
}catch(Exception e){
e.printStackTrace();
Toast.makeText(getContext(),e.getMessage(), Toast.LENGTH_LONG);
return null;
}
}
private Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback(){
@Override
public void onShutter() {
if(mTakePictureListener!=null)
mTakePictureListener.onShutter();
}
};
private static String TAG = "CameraPreview";
public interface TakePictureListener{
public void onTakePicture(Bitmap bitmap);
public void onPostPreview(Bitmap image);
public void onShutter();
}
public CameraPreview(Context context,SurfaceView surfaceView,FrameLayout surfaceFrame) {
super(context);
mSurfaceView = surfaceView;
mSurfaceFrame = surfaceFrame;
setFrameSize();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Log.v(TAG,"Contructor finished");
}
private void justTakeTheDamPicture(){
mCamera.takePicture(shutterCallback, null, postPreviewCallback, takePictureCallback);
}
private void setCameraParameters() {
Camera.Parameters parameters = mCamera.getParameters();
if(mPreviewSizes==null)
mPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
if(mPreviewSize==null){
for(Camera.Size size : mPreviewSizes){
if(mPreviewSize==null || mPreviewSize.width<size.width){
mPreviewSize = size;
if(mPreviewSize.width>mScreenSize.x) break;
}
}
}
Log.v(TAG,"Preview Size: "+mPreviewSize.width+"x"+mPreviewSize.height);
LayoutParams surfaceViewParams = mSurfaceView.getLayoutParams();
float scaleFactor = 0;
if(android.os.Build.VERSION.SDK_INT >= 8)
{ // If API >= 8 -> rotate display...
mCamera.setDisplayOrientation(90);
// when rotated, need to interchange
scaleFactor = (float)mFrameSize/mPreviewSize.height;
surfaceViewParams.width = (int) (mPreviewSize.height*scaleFactor);
surfaceViewParams.height = (int) (mPreviewSize.width*scaleFactor);
}else{
scaleFactor = (float)mFrameSize/mPreviewSize.width;
surfaceViewParams.width = (int) (mPreviewSize.width*scaleFactor);
surfaceViewParams.height = (int) (mPreviewSize.height*scaleFactor);
}
mSurfaceView.setLayoutParams(surfaceViewParams);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
if(parameters.getFocusMode()!=null){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
if(parameters.getFlashMode()!=null){
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
}
// Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE does not work on some samsung devices
// so try and catch the error and revert to Camera.Parameters.FOCUS_MODE_AUTO
try{
mCamera.setParameters(parameters);
}catch(RuntimeException e){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
e.printStackTrace();
}
}
private void setFrameSize() {
LayoutParams surfaceLayoutParams = mSurfaceFrame.getLayoutParams();
Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
mScreenSize = new Point();
display.getSize(mScreenSize);
mFrameSize = mScreenSize.x;
surfaceLayoutParams.width = mFrameSize;
surfaceLayoutParams.height = mFrameSize;
mSurfaceFrame.setLayoutParams(surfaceLayoutParams);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
if(mCamera!=null){
setCameraParameters();
// Important: Call startPreview() to start updating the preview surface.
// Preview must be started before you can take a picture.
mCamera.startPreview();
Log.v(TAG,"preview started");
}
Log.v(TAG,"SurfaceChanged finished");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(mCamera != null)
{
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
Log.v(TAG,"SurfaceDestroyed finished");
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera() {
if (mCamera != null) {
// Call stopPreview() to stop updating the preview surface.
mCamera.stopPreview();
// Important: Call release() to release the camera for use by other
// applications. Applications should release the camera immediately
// during onPause() and re-open() it during onResume()).
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
stopPreviewAndFreeCamera();
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
setCameraParameters();
} catch (Exception e)
{
if(mCamera!=null){
mCamera.release();
mCamera = null;
}
e.printStackTrace();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
public void takePicture(){
if(mCamera!=null){
try{
if(mCamera.getParameters().getFocusMode()==Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE){
mCamera.autoFocus(onFocus);
}else{
justTakeTheDamPicture();
}
}catch(Exception e){
e.printStackTrace();
justTakeTheDamPicture();
}
}
}
public void setTakePictureListener(TakePictureListener l){
mTakePictureListener = l;
}
public Camera getCamera(){
return mCamera;
}
以下是Capture Fragment的代码
private OnClickListener onCapture = new OnClickListener(){
@Override
public void onClick(View v) {
if(mPreview!=null){
mPreview.takePicture();
}
}
};
private CameraPreview.TakePictureListener takePictureListener = new CameraPreview.TakePictureListener() {
@Override
public void onTakePicture(Bitmap bitmap) {
Capture cap = Capture.getInstance(getActivity());
cap.setUri(bitmapToFile(bitmap));
//cap.save();
showLastCroppped();
changeCaptureStatus(CaptureStatus.HasImageNoFields);
}
@Override
public void onShutter() {
changeCaptureStatus(CaptureStatus.TakingPicture);
}
@Override
public void onPostPreview(Bitmap image) {
imagePreviewContainer.setImageBitmap(image);
imagePreviewContainer.setVisibility(View.VISIBLE);
}
};
private Uri bitmapToFile(Bitmap bmp){
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Alliwant";
SimpleDateFormat simpleDate = new SimpleDateFormat("ddMMyy-hhmmss.SSS");
File dir = new File(file_path);
if(!dir.exists())
dir.mkdirs();
String filename = simpleDate.format( new Date() );
File file = new File(dir, "gift" + filename + ".png");
FileOutputStream fOut;
Uri fileUri = null;
try {
fOut = new FileOutputStream(file);
fileUri = Uri.fromFile(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
bmp.compress(Bitmap.CompressFormat.PNG, 85, fOut);
try {
fOut.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
try {
fOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return fileUri;
}
答案 0 :(得分:0)
您的系统内存(不是磁盘空间)已用完,导致OOM错误。
检查您的来电
Bitmap.createBitmap
Bitmap.createScaledBitmap
考虑减少位图大小,或see this for one approach
答案 1 :(得分:0)
这确实是一个内存不足的问题,处理位图需要大量的内存分配,特别是大尺寸的图像(就像我的1920年那样)。我能够通过允许应用程序使用大堆内存,在应用程序标记中的android清单中添加一行来解决它。
android:largeHeap="true"
我不知道这是否是解决问题的最佳方法,但我发现这是一个很好的方法,因为我不必妥协改变已设定的大小。如果你有更好的解决方案,请评论。谢谢! :)