我收到一个RuntimeException“在调用Camera.release()之后正在使用Camera”,当我最小化应用程序然后重新打开应用程序时。该应用程序没有崩溃,所以我想知道它是否值得关注?如果是这样,我该如何解决这个问题?我在网上找不到任何有用的东西。此外,当屏幕旋转更改时,没有错误。我想这是因为相机旋转是在surfaceCreated()...
中处理的 05-21 11:09:14.405 15474-15474/? I/zygote64: Late-enabling -Xcheck:jni
05-21 11:09:14.445 15474-15489/? E/zygote64: Failed writing handshake bytes (-1 of 14): Broken pipe
05-21 11:09:14.445 15474-15489/? I/zygote64: Debugger is no longer active
05-21 11:09:14.549 15474-15474/? I/InstantRun: starting instant run server: is main process
05-21 11:09:14.650 15474-15474/? D/TAG: onCreate() called
05-21 11:09:14.651 15474-15474/? D/TAG: onStart() called
05-21 11:09:14.656 15474-15474/? E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:14.651 15474-15474/? W/ojectLightCycle: type=1400 audit(0.0:211090): avc: denied { read } for name="u:object_r:camera_prop:s0" dev="tmpfs" ino=22601 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:camera_prop:s0 tclass=file permissive=0 ppid=2713 pcomm="main" pgid=2713 pgcomm="main"
05-21 11:09:14.651 15474-15474/? D/TAG: onStart() called
05-21 11:09:14.656 15474-15474/? E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:14.693 15474-15474/? D/getCameraInstance(): Camera is available
05-21 11:09:14.717 15474-15474/? D/TAG: onResume() called
05-21 11:09:14.728 15474-15586/? D/OpenGLRenderer: HWUI GL Pipeline
05-21 11:09:14.785 15474-15586/? I/Adreno: QUALCOMM build : 3953ab1, Ib515ec08c2
Build Date : 09/27/17
OpenGL ES Shader Compiler Version: EV031.20.00.04
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.6.4.R1.08.00.00.309.032
Remote Branch : NONE
Reconstruct Branch : NOTHING
05-21 11:09:14.785 15474-15586/? I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8998.so from the current namespace instead.
05-21 11:09:14.789 15474-15586/? I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
05-21 11:09:14.792 15474-15586/? I/OpenGLRenderer: Initialized EGL, version 1.4
05-21 11:09:14.792 15474-15586/? D/OpenGLRenderer: Swap behavior 2
05-21 11:09:14.800 15474-15474/? D/Picture Size: Supported Size - Width: 5056 Height: 3792
Supported Size - Width: 5504 Height: 3096
Supported Size - Width: 4000 Height: 3000
Supported Size - Width: 4608 Height: 2592
Supported Size - Width: 3840 Height: 2160
Supported Size - Width: 3264 Height: 2448
Supported Size - Width: 2048 Height: 1536
Supported Size - Width: 1920 Height: 1080
Supported Size - Width: 1280 Height: 720
Supported Size - Width: 720 Height: 480
Supported Size - Width: 640 Height: 480
Supported Size - Width: 480 Height: 320
Supported Size - Width: 352 Height: 288
Supported Size - Width: 320 Height: 240
Supported Size - Width: 176 Height: 144
Supported Size set to - Width: 5056 Height: 3792
05-21 11:09:15.050 15474-15586/? I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8998.so from the current namespace instead.
05-21 11:09:30.906 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onPause() called
05-21 11:09:30.940 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStop() called
05-21 11:09:32.033 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStart() called
05-21 11:09:32.037 15474-15474/com.example.saili.ProjectLightCycle E/libc: Access denied finding property "camera.hal1.packagelist"
05-21 11:09:32.099 15474-15474/com.example.saili.ProjectLightCycle D/getCameraInstance(): Camera is available
05-21 11:09:32.125 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onResume() called
05-21 11:09:32.146 15474-15474/com.example.saili.ProjectLightCycle E/SurfaceView: Exception configuring surface
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.native_getParameters(Native Method)
at android.hardware.Camera.getParameters(Camera.java:2027)
at com.example.saili.ProjectLightCycle.ShowCamera.surfaceCreated(ShowCamera.java:43)
at android.view.SurfaceView.updateSurface(SurfaceView.java:664)
at android.view.SurfaceView.setFrame(SurfaceView.java:344)
at android.view.View.layout(View.java:19587)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:768)
at android.view.View.layout(View.java:19590)
at android.view.ViewGroup.layout(ViewGroup.java:6053)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2488)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2204)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1390)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6754)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
at android.view.Choreographer.doCallbacks(Choreographer.java:778)
at android.view.Choreographer.doFrame(Choreographer.java:713)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:251)
at android.app.ActivityThread.main(ActivityThread.java:6572)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
05-21 11:09:32.168 15474-15474/com.example.saili.ProjectLightCycle D/Picture Size: Supported Size - Width: 5056 Height: 3792
Supported Size - Width: 5504 Height: 3096
Supported Size - Width: 4000 Height: 3000
Supported Size - Width: 4608 Height: 2592
Supported Size - Width: 3840 Height: 2160
Supported Size - Width: 3264 Height: 2448
Supported Size - Width: 2048 Height: 1536
Supported Size - Width: 1920 Height: 1080
Supported Size - Width: 1280 Height: 720
Supported Size - Width: 720 Height: 480
Supported Size - Width: 640 Height: 480
Supported Size - Width: 480 Height: 320
Supported Size - Width: 352 Height: 288
Supported Size - Width: 320 Height: 240
05-21 11:09:32.169 15474-15474/com.example.saili.ProjectLightCycle D/Picture Size: Supported Size - Width: 176 Height: 144
Supported Size set to - Width: 5056 Height: 3792
05-21 11:09:38.611 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onPause() called
05-21 11:09:38.640 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onStop() called
05-21 11:09:39.737 15474-15474/com.example.saili.ProjectLightCycle D/TAG: onDestroy() called
这是我的主要活动
package com.example.saili.ProjectLightCycle;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
{
Camera camera;
FrameLayout frameLayout;
ShowCamera showCamera;
String toastString;
private GestureDetectorCompat detector;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("TAG", "onCreate() called");
}
@Override
protected void onStart()
{
super.onStart();
Log.d("TAG", "onStart() called");
frameLayout = (FrameLayout) findViewById(R.id.frameLayout);
// open the camera
camera = getCameraInstance();
// create a showCamera object
showCamera = new ShowCamera(this, camera);
// add the view to the frameLayout to diplay the camera's view on the screen
frameLayout.addView(showCamera);
// Auto focus the camera preview
Camera.Parameters parameters = camera.getParameters();
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
camera.setParameters(parameters);
detector = new GestureDetectorCompat(this, this);
}
@Override
protected void onResume()
{
super.onResume();
Log.d("TAG", "onResume() called");
}
@Override
protected void onPause()
{
camera.setPreviewCallback(null);
releaseCamera();
super.onPause();
Log.d("TAG", "onPause() called");
}
@Override
protected void onStop()
{
super.onStop();
Log.d("TAG", "onStop() called");
}
@Override
protected void onDestroy()
{
super.onDestroy();
Log.d("TAG", "onDestroy() called");
}
Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback()
{
@Override
public void onShutter()
{
toastString = "Picture Captured!";
toast(toastString);
}
};
// saves the image to the external storage
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File picture_file = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (picture_file == null)
{
Log.d("MainActivity", "Picture_file == null");
return;
}
else
{
Log.d("MainActivity", "Picture_file != null");
try
{
FileOutputStream fileOutputStream = new FileOutputStream(picture_file);
fileOutputStream.write(data);
Log.d("MainActivity", "Data written!");
fileOutputStream.close();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(picture_file));
sendBroadcast(intent);
// this commented out method would resume camera live preview
//camera.startPreview();
}
catch (FileNotFoundException e)
{
Log.d("MainActivity", "File not Found");
}
catch (IOException e)
{
Log.d("MainActivity", "Write IOException thrown!");
e.printStackTrace();
}
}
}
};
private File getOutputMediaFile(int type)
{
String state = Environment.getExternalStorageState();
if (!state.equals(Environment.MEDIA_MOUNTED))
{
Log.d("MainActivity", "Media Not Mounted!");
return null;
}
else
{
Log.d("MainActivity", "Media Mounted!");
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "WhatsThisApp");
String picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "WhatsThisApp";
Log.d("MainActivity", picDir);
//create the storage directory if it does not exist
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
Log.d("MainActivity", "Failed to create directory");
return null;
}
}
// create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
Log.d("MainActivity", "File name created!");
}
else
{
Log.d("MainActivity", "File name not created!");
return null;
}
return mediaFile;
}
}
public void captureImage(View v)
{
if(camera != null)
{
camera.takePicture(mShutterCallback,null,mPictureCallback);
Log.d("MainActivity", "Picture Taken!");
}
}
public static Camera getCameraInstance()
{
Camera c = null;
try
{
c = Camera.open(); // Camera.open() method will open the first back facing camera on the device
// to access a different camera use Camera.open(int)
Log.d("getCameraInstance()", "Camera is available");
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
Log.d("getCameraInstance()", "Camera is not available (in use or does not exist)");
}
return c;
}
// toast method
public void toast(String toastString)
{
Context context = getApplicationContext();
CharSequence text = toastString;
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
// swip funtionality
@Override
public boolean onDown(MotionEvent e)
{
return false;
}
@Override
public void onShowPress(MotionEvent e)
{
}
@Override
public boolean onSingleTapUp(MotionEvent e)
{
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
return false;
}
@Override
public void onLongPress(MotionEvent e)
{
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
//Intent intent = new Intent(this, Main2Activity.class);
// startActivity(intent);
return true; // which says that I handled this event
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private void releaseCamera()
{
if (camera != null)
{
camera.release();
camera = null;
}
}
}
这是我的SHowCamera课程
package com.example.saili.ProjectLightCycle;
import android.content.Context;
import android.content.res.Configuration;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.hardware.Camera;
import java.io.IOException;
import java.util.List;
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback
{
Camera camera;
SurfaceHolder holder;
public ShowCamera(Context context, Camera camera)
{
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
Camera.Parameters parameters = camera.getParameters();
// finds the supported picture sizes
List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
Camera.Size mSize = null;
for (Camera.Size size : supportedPictureSizes)
{
mSize = size;
Log.d("Picture Size", "Supported Size - Width: " + mSize.width + " Height: " + mSize.height);
}
// sets the picture size to the first available picture size higher than width 720 and height 480
for (Camera.Size size : supportedPictureSizes)
{
mSize = size;
if (mSize.width > 720 && mSize.height > 480)
{
break;
}
}
Log.d("Picture Size", "Supported Size set to - Width: " + mSize.width + " Height: " + mSize.height);
if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
{
parameters.set("orientation", "portrait");
camera.setDisplayOrientation(90);
parameters.setRotation(90);
}
else
{
parameters.set("Orientation", "landscape");
camera.setDisplayOrientation(0);
parameters.setRotation(0);
}
parameters.setPictureSize(mSize.width, mSize.height);
camera.setParameters(parameters);
try
{
camera.setPreviewDisplay(holder);
camera.startPreview();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
根据Activity Reference当另一个活动进入前台时,将调用 onPause 方法。在用户返回活动后,将调用 onResume 方法,但不会调用 onCreate 。这样您就应该在 onResume 而不是 onCreate 上设置相机。
获取/发布任何类型的资源应始终是对称的。如果在 onStart 获取,则在 onStop realease 。如果获取 on onResume ,则发布 onPause 。
希望它有效!
答案 1 :(得分:0)
因此,对于我发布的原始问题,RuntimeException“在调用Camera.release()之后正在使用Camera”,解决方案在Logcat日志中详细说明(参见上面的日志)。我碰巧注意到在onStart()和onResume()之后我已经调用了这个错误。我说得好,当然,在Camera.release被叫之后相机正在被使用!所以,我只需要为onResume()取消调用Camera.release。
这是我最终做的事情,现在我不再在我最小化应用程序并最小化它时得到错误。可能还有另一种或更好的方法可以实现这一目标,但这对我来说是有效的。
@Override
protected void onResume()
{
super.onResume();
if (camera == null)
{
showCameraMethod();
}
detector = new GestureDetectorCompat(this, this);
Log.d("TAG", "onResume() called");
}
@Override
protected void onPause()
{
super.onPause();
if (camera != null)
{
showCamera.getHolder().removeCallback(showCamera);
camera.release(); // release the camera for other applications
camera = null;
}
Log.d("TAG", "onPause() called");
}