如果我尝试在关闭屏幕的服务中使用相机,则相机最终会锁定并无法使用,手机将重新启动,或者相机驱动程序会出现段错(mm-camera)。从相机锁定或mm-camera segfaulting中恢复的唯一方法是重启设备。如果相机上的屏幕不能正常工作,似乎相机直接绑在屏幕上。如果手机已插入我的电脑并且Android调试正在运行,则相机不会遇到相同的问题。我已经采用了几种代码变体,甚至尝试使用OpenCV的VideoCapture类,它不需要Surface并完全绕过android.hardware.Camera,但结果是一样的:如果我在屏幕上运行它就可以正常工作,如果我用相机屏幕关闭它会锁定。这是相机代码的错误还是故意放入?有人在屏幕关闭时使用相机取得了成功吗?
我已在以下设备上对此进行了测试 摩托罗拉RAZR M. 三星Galaxy S3(Pre 4.3更新)* 三星Galaxy Note 3 华硕Transformer TF700 Nexus 7 Gen 2 LG G2
*带有4.3更新的三星Galaxy S3没有表现出这种行为。
尝试在坏状态下使用相机的Logcat,注意errno 16是EBUSY
I CameraHalWatchdog: Starting Watchdog Thread...
E mm-camera-hal: mm_camera_ops_close: my_obj=0x4151b008
E mm-camera-hal: mm_camera_ops_close: ref_count=0
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 45, read_len = 52, expect_len = 52
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 35, read_len = 52, expect_len = 52
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 37, read_len = 52, expect_len = 52
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 39, read_len = 52, expect_len = 52
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 43, read_len = 52, expect_len = 52
I CameraHalWatchdog: Stopped Watchdog Thread...
I CameraHalWatchdog: Starting Watchdog Thread...
E mm-camera-hal: mm_camera_ops_open: g_cam_ctrl.cam_obj[camera_id] =0x4151b008, camera_id = 0
E mm-camera-hal: mm_camera_ops_open: poll_threads[0].data.used = 0
E mm-camera-hal: mm_camera_ops_open: poll_threads[1].data.used = 0
E mm-camera-hal: mm_camera_ops_open: poll_threads[2].data.used = 0
E mm-camera-hal: Errno:16
E mm-camera-hal: mm_camera_open: ctrl_fd = -1
E mm-camera-hal: mm_camera_open: opened, break out while loop
E mm-camera-hal: mm_camera_open: after while loop
E mm-camera-hal: mm_camera_open: cannot open control fd of 'video0' Errno = 16
E mm-camera-hal: mm_camera_ops_close: my_obj=0x0
I CameraHalWatchdog: Stopped Watchdog Thread...
摩托罗拉RAZR M mm相机的Logcat
E mm-camera-hal: Run thread for ch_type = 0
E mm-camera-hal: mm_camera_poll_thread_add_ch : my_obj = 0x41960008, poll_cb = 0x41973d00, poll_cb->data.used = 1
E mm-camera: config_decide_vfe_outputs Current mode 0 Full size liveshot : Disabled
E mm-camera: config_decide_vfe_outputs: Ports Used 1, Op mode 64
E mm-camera: config_decide_vfe_outputs: Primary: 1920x1080, extra_pad: 0x0, Fmt: 1, Type: 1, Path: 1
E mm-camera: config_decide_vfe_outputs: Secondary: 1920x1080, extra_pad: 0x0, Fmt: 0, Type: 0, Path: 0
E mm-camera: config_set_op_mode_to_mctl_pp_video Camcorder configured in Low Power mode.
E mm-camera: config_MSM_V4L2_STREAM_ON Sending START CMD to VFE
E mm-camera: config_CAMERA_START_VIDEO: received CAMERA_START_VIDEO!, ctrl->state = 0
E mm-camera: zoom_get_crop_factor: crop_factor = 4096
E mm-camera: sensor_load_chromatix: libchromatix_ov8820_video_hd.so: 31
E mm-camera: load_chromatix:37: for video hd chromatix_version=520
E mm-camera: sensor_load_chromatix:235: dlclose(libchromatix_handle) refcount 0
E mm-camera: config_MSG_ID_RESET_ACK Writing aec data to sensor: Real Gain 1.000000 Line count 1599
E mm-camera-hal: mm_camera_poll_proc_pipe: read_fd = 35, read_len = 52, expect_len = 52
E mm-camera-hal: mm_camera_poll_proc_pipe: poll_cb = 0x41973d00, poll_cb->data.used =1, Num fds after MM_CAMERA_PIPE_CMD_ADD_CH = 2
E mm-camera: vfe_config_mode: VideoCFg config 7ffffff
E mm-camera: vfe_operation_config: format 1
E mm-camera: vfe_operation_config:vfe_op_mode=4
F libc : Fatal signal 11 (SIGSEGV) at 0xc0debadd (code=1), thread 3400 (mm-qcamera-daem)
I DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I DEBUG : Build fingerprint: 'motorola/XT907_verizon/scorpion_mini:4.1.2/9.8.1Q-94/76:user/release-keys'
I DEBUG : pid: 321, tid: 3400, name: mm-qcamera-daem >>> /system/bin/mm-qcamera-daemon <<<
I DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr c0debadd
I DEBUG : r0 41dab6b0 r1 deadbeef r2 00000000 r3 c0debadd
I DEBUG : r4 413d595c r5 00000000 r6 41d803e8 r7 413d595c
I DEBUG : r8 413d5908 r9 40186acc sl 41d803e8 fp 00000008
I DEBUG : ip 80000000 sp 413d5810 lr 41d93be8 pc 401a3150 cpsr 80000030
I DEBUG : d0 c2dc0000001fa400 d1 000000f140a00000
I DEBUG : d2 ffffffcd43710000 d3 000000eac24c0000
I DEBUG : d4 ffffff92436a0000 d5 43180000c2dc0000
I DEBUG : d6 002f760000000005 d7 4147bb0000000000
I DEBUG : d8 0000000000000000 d9 0000000000000000
I DEBUG : d10 0000000000000000 d11 0000000000000000
I DEBUG : d12 0000000000000000 d13 0000000000000000
I DEBUG : d14 0000000000000000 d15 0000000000000000
I DEBUG : d16 0000000000000000 d17 0000000000000000
I DEBUG : d18 0000000000000000 d19 0000000000000000
I DEBUG : d20 0000000000000000 d21 0000000000000000
I DEBUG : d22 0000000000000000 d23 0000000000000000
I DEBUG : d24 c020000000000000 d25 3fe0000000000000
I DEBUG : d26 4021000000000000 d27 4020000000000000
I DEBUG : d28 3fe0000000000000 d29 3fe0000000000000
I DEBUG : d30 0000000000000000 d31 bfe0000000000000
I DEBUG : scr 60000011
I DEBUG :
I DEBUG : backtrace:
I DEBUG : #00 pc 0001b150 /system/lib/liboemcamera.so (mctl_proc_v4l2_request+1667)
I DEBUG : #01 pc 0001d39f /system/lib/liboemcamera.so
I DEBUG : #02 pc 00012ef0 /system/lib/libc.so (__thread_entry+48)
I DEBUG : #03 pc 00012648 /system/lib/libc.so (pthread_create+172)
I DEBUG :
I DEBUG : stack:
I DEBUG : 413d57d0 00000000
I DEBUG : 413d57d4 00000000
I DEBUG : 413d57d8 00000000
I DEBUG : 413d57dc 00000000
I DEBUG : 413d57e0 00000000
I DEBUG : 413d57e4 00000000
I DEBUG : 413d57e8 4019916b /system/lib/liboemcamera.so (mmcamera_stacktrace+18)
I DEBUG : 413d57ec 413d595c
I DEBUG : 413d57f0 0000000b
I DEBUG : 413d57f4 41d803e8 [heap]
I DEBUG : 413d57f8 413d595c
I DEBUG : 413d57fc 413d5908
I DEBUG : 413d5800 40186acc
I DEBUG : 413d5804 41d803e8 [heap]
I DEBUG : 413d5808 df0027ad
I DEBUG : 413d580c 00000000
I DEBUG : #00 413d5810 00000000
I DEBUG : 413d5814 00000000
I DEBUG : 413d5818 00000000
I DEBUG : 413d581c 00000000
I DEBUG : 413d5820 00000001
I DEBUG : 413d5824 413d595c
I DEBUG : 413d5828 40186acc
I DEBUG : 413d582c 401a3477 /system/lib/liboemcamera.so (mctl_proc_event_message+490)
I DEBUG : 413d5830 00000000
I DEBUG : 413d5834 00000000
I DEBUG : 413d5838 00000000
I DEBUG : 413d583c 00000000
I DEBUG : 413d5840 00000000
I DEBUG : 413d5844 00000000
I DEBUG : 413d5848 00000000
I DEBUG : 413d584c 00000000
I DEBUG : ........ ........
I DEBUG : #01 413d58e0 00000008
I DEBUG : 413d58e4 0000000a
I DEBUG : 413d58e8 00000000
I DEBUG : 413d58ec 41d803e8 [heap]
I DEBUG : 413d58f0 ffffffff
I DEBUG : 413d58f4 ffffffff
I DEBUG : 413d58f8 00000007
I DEBUG : 413d58fc 40186acc
I DEBUG : 413d5900 ffffffff
I DEBUG : 413d5904 ffffffff
I DEBUG : 413d5908 00000000
I DEBUG : 413d590c 00000000
I DEBUG : 413d5910 00000000
I DEBUG : 413d5914 00000000
I DEBUG : 413d5918 00000000
I DEBUG : 413d591c 00000000
I DEBUG : ........ ........
I DEBUG : #02 413d6ef0 41dab590 [heap]
I DEBUG : 413d6ef4 413d6f00
I DEBUG : 413d6ef8 40170054 /system/lib/libc.so
I DEBUG : 413d6efc 4014864c /system/lib/libc.so (pthread_create+176)
I DEBUG :
I DEBUG : memory near r0:
I DEBUG : 41dab690 00000000 00000000 00000000 00000000 ................
I DEBUG : 41dab6a0 00000000 00000000 00000000 00000006 ................
I DEBUG : 41dab6b0 00000001 00000000 00000001 00002710 .............'..
I DEBUG : 41dab6c0 00000007 00000000 000000f1 00000001 ................
I DEBUG : 41dab6d0 00000000 000007b1 30303031 00303030 ........1000000.
I DEBUG :
I DEBUG : memory near r4:
I DEBUG : 413d593c 00000001 ffffffff 00000001 ffffffff ................
I DEBUG : 413d594c 00000001 ffffffff 00000001 00000004 ................
I DEBUG : 413d595c 00000001 413d5ac4 00000000 00002710 .....Z=A.....'..
I DEBUG : 413d596c 00000007 00000000 000000f2 00000001 ................
I DEBUG : 413d597c 00000000 00000000 00000000 00000000 ................
I DEBUG :
I DEBUG : memory near r6:
I DEBUG : 41d803c8 00000000 00000000 00000000 00000000 ................
I DEBUG : 41d803d8 00000000 00000000 00000000 00000007 ................
I DEBUG : 41d803e8 0000000b 00000000 00000000 00000000 ................
I DEBUG : 41d803f8 00000000 00000000 00000000 00000000 ................
I DEBUG : 41d80408 00000000 00000004 00000000 00000004 ................
I DEBUG :
I DEBUG : memory near r7:
I DEBUG : 413d593c 00000001 ffffffff 00000001 ffffffff ................
I DEBUG : 413d594c 00000001 ffffffff 00000001 00000004 ................
I DEBUG : 413d595c 00000001 413d5ac4 00000000 00002710 .....Z=A.....'..
I DEBUG : 413d596c 00000007 00000000 000000f2 00000001 ................
I DEBUG : 413d597c 00000000 00000000 00000000 00000000 ................
I DEBUG :
I DEBUG : memory near r8:
I DEBUG : 413d58e8 00000000 41d803e8 ffffffff ffffffff .......A........
I DEBUG : 413d58f8 00000007 40186acc ffffffff ffffffff .....j.@........
I DEBUG : 413d5908 00000000 00000000 00000000 00000000 ................
I DEBUG : 413d5918 00000000 00000000 00000000 00000000 ................
I DEBUG : 413d5928 0000000b 00000002 00000008 00010003 ................
I DEBUG :
I DEBUG : memory near r9:
I DEBUG : 40186aac 00000000 00000000 00000000 00000000 ................
I DEBUG : 40186abc 00000000 00000000 00000000 00000000 ................
I DEBUG : 40186acc e362c3df 00000000 00000000 00000000 ..b.............
I DEBUG : 40186adc 00000000 00000000 00000000 00000000 ................
I DEBUG : 40186aec 00000000 00000000 00000000 00000000 ................
I DEBUG :
I DEBUG : memory near sl:
I DEBUG : 41d803c8 00000000 00000000 00000000 00000000 ................
I DEBUG : 41d803d8 00000000 00000000 00000000 00000007 ................
I DEBUG : 41d803e8 0000000b 00000000 00000000 00000000 ................
I DEBUG : 41d803f8 00000000 00000000 00000000 00000000 ................
I DEBUG : 41d80408 00000000 00000004 00000000 00000004 ................
I DEBUG :
I DEBUG : memory near ip:
I DEBUG : 7fffffe0 ffffffff ffffffff ffffffff ffffffff ................
I DEBUG : 7ffffff0 ffffffff ffffffff ffffffff ffffffff ................
I DEBUG : 80000000 ffffffff ffffffff ffffffff ffffffff ................
I DEBUG : 80000010 ffffffff ffffffff ffffffff ffffffff ................
I DEBUG : 80000020 ffffffff ffffffff ffffffff ffffffff ................
I DEBUG :
I DEBUG : memory near sp:
I DEBUG : 413d57f0 0000000b 41d803e8 413d595c 413d5908 .......A\Y=A.Y=A
I DEBUG : 413d5800 40186acc 41d803e8 df0027ad 00000000 .j.@...A.'......
I DEBUG : 413d5810 00000000 00000000 00000000 00000000 ................
I DEBUG : 413d5820 00000001 413d595c 40186acc 401a3477 ....\Y=A.j.@w4.@
I DEBUG : 413d5830 00000000 00000000 00000000 00000000 ................
I DEBUG :
I DEBUG : code around pc:
I DEBUG : 401a3130 2a00316c f103d042 605a0224 316cf8d6 l1.*B...$.Z`..l1
I DEBUG : 401a3140 f506e036 f8de3e9c b1100168 4b2d492c 6....>..h...,I-K
I DEBUG : 401a3150 88606019 369cf506 f7ef3024 f8c6fd9b .``....6$0......
I DEBUG : 401a3160 b9c00168 20064e31 447e4a31 447a4b31 h...1N. 1J~D1KzD
I DEBUG : 401a3170 4631447b eb0af7ef 49206920 f7ef4622 {D1F.... i I"F..
I DEBUG :
I DEBUG : code around lr:
I DEBUG : 41d93bc8 00000000 00000000 00000000 04380780 ..............8.
I DEBUG : 41d93bd8 00000000 00000000 00000000 00000000 ................
I DEBUG : 41d93be8 00000000 00000002 001fa400 00000000 ................
I DEBUG : 41d93bf8 000fd200 00000000 00000000 00000000 ................
I DEBUG : 41d93c08 00000000 00000000 00000000 00000000 ................
I DEBUG :
I DEBUG : memory map around fault addr c0debadd:
I DEBUG : beee1000-bef02000 [stack]
I DEBUG : (no map for address)
I DEBUG : ffff0000-ffff1000 [vectors]
I BootReceiver: Copying /data/tombstones/tombstone_00 to DropBox (SYSTEM_TOMBSTONE)
E mm-camera:
E mm-camera: Camera Daemon starting
E mm-camera: qcamsvr_start: old_mode = 3f
每5分钟在服务中运行相机的最简单测试代码,需要200个预览帧,并在无法获取相机时发出通知。
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class DummyService extends Service implements PreviewCallback, SurfaceHolder.Callback
{
// might need a way to determine who is telling us what to do
public static final String BUNDLE_TAG_SOURCE = "source";
public static final String SOURCE_ALARM_MANAGER = "AlarmManager";
public static final int ALARM_PERIOD_IN_MINUTES = 1;
public static final int ALARM_PERIOD_IN_MSEC = ALARM_PERIOD_IN_MINUTES*60*1000;
final int NumberOfFrames = 200;
int framesLeft = NumberOfFrames;
int width = 0;
int height = 0;
Camera camera;
final int AlarmMinutes = 5;
int alarmMinutesLeft = 0;
boolean isProcessing = false;
// gets invoked once - gets invoked via StartServiceBroadcastReceiver when the phone is started
@Override
public void onCreate()
{
Log("DummyService: onCreate");
setupAlarmManager();
// Start foreground service to avoid unexpected kill
Notification notification = new Notification.Builder(this)
.setContentTitle("Background Video Recorder")
.setContentText("")
.setSmallIcon(R.drawable.ic_launcher)
.build();
startForeground(1234, notification);
}
synchronized void setProcessing(boolean processing)
{
isProcessing = processing;
}
synchronized boolean isProcessing()
{
return isProcessing;
}
// gets invoked each time startService is called or via alarm manage
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if(!isProcessing() && (alarmMinutesLeft <= 0))
{
WindowManager wm = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
// on a G-slate tablet seems to always be visible; putting in upper left corner
WindowManager.LayoutParams params = new WindowManager.LayoutParams(1, 1, -2000, -2000, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSLUCENT);
SurfaceView surfaceView = new SurfaceView(this);
surfaceView.setZOrderOnTop(false);
surfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT);
// crashed here (unable to add window - permission denied for this windows type), fixed with <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
wm.addView(surfaceView, params);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
// going to add a callback to the surface holder
surfaceHolder = surfaceView.getHolder();
// this starts the process of getting the camera
surfaceHolder.addCallback(this);
// deprecated but we'll leave it
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
else
{
Log("Alarm Minutes Left: " + alarmMinutesLeft);
alarmMinutesLeft--;
}
return START_STICKY; // run until it is explicitly stopped
}
// always going to fire alarms
private void setupAlarmManager()
{
Log("setupAlarmManager() ");
// define an intent to be fired periodically
Intent intent = new Intent(this, DummyService.class);
intent.putExtra(BUNDLE_TAG_SOURCE, SOURCE_ALARM_MANAGER);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); // flag ensures the bundle can be received
// the following causes onStartCommand to be invoked every 60 seconds
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating (AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), ALARM_PERIOD_IN_MSEC, pendingIntent);
}
// bind related
public final IBinder binder = new DummyServiceBinder();
public class DummyServiceBinder extends Binder
{
public DummyService getService()
{
return DummyService.this;
}
}
@Override
public IBinder onBind(Intent arg0)
{
return binder;
}
@SuppressLint("NewApi")
public void notifyUser()
{
Notification.Builder mBuilder =
new Notification.Builder(this)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Camera Locked")
.setContentText("Camera Locked")
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setPriority(Notification.PRIORITY_HIGH);
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(999, mBuilder.build());
}
public static void Log(String info)
{
android.util.Log.i("Dummy", info);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera)
{
if(framesLeft > 0)
{
int expectedBytes = width * height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
camera.addCallbackBuffer(new byte[expectedBytes]);
if(framesLeft % 100 == 0)
{
Log("FramesLeft: " + framesLeft);
}
framesLeft--;
}
else
{
Log("Frames Completed");
if(camera != null)
{
camera.setPreviewCallbackWithBuffer(null);
camera.stopPreview();
camera.release();
camera = null;
}
alarmMinutesLeft = AlarmMinutes;
setProcessing(false);
framesLeft = 200;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
Log("surfaceCreated");
try
{
camera = Camera.open();
}
catch (Exception ex)
{
notifyUser();
camera = null;
alarmMinutesLeft = AlarmMinutes;
setProcessing(false);
Log("Exception while opening camera: " + ex.getMessage());
}
if(camera != null)
{
try
{
setProcessing(true);
// set up preview
camera.setPreviewCallbackWithBuffer(this);
camera.setPreviewDisplay(holder);
Camera.Parameters p = camera.getParameters();
//get highest preview resolution
List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes();
class SizeCompare implements Comparator<Camera.Size> {
public int compare(Camera.Size lhs, Camera.Size rhs) {
if (lhs.width < rhs.width) return 1;
if (lhs.width > rhs.width) return -1;
if (lhs.height < rhs.height) return 1;
if (lhs.height > rhs.height) return -1;
return 0;
}
};
SizeCompare s = new SizeCompare();
TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s);
sortedResolutions.addAll(unsortedSizes);
ArrayList<Camera.Size> mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions);
width = mPreviewSizes.get(0).width;
height = mPreviewSizes.get(0).height;
Log("Using preview size of " + width + "x" + height);
p.setPreviewFormat(ImageFormat.NV21);
p.setPreviewSize(width, height);
camera.setParameters(p);
camera.startPreview();
int expectedBytes = width * height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
camera.addCallbackBuffer(new byte[expectedBytes]);
}
catch (Exception exception)
{
camera.release();
camera = null;
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log("surfaceChanged");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log("surfaceDestroyed");
}
}
答案 0 :(得分:0)
开启屏幕0.5秒 - 当服务使用相机屏幕关闭时。 我尝试了很多Android手机。 它始终有效。 但我不知道为什么@@?
如果在没有开启屏幕的情况下使用屏幕关闭相机0.5秒 相机总是锁定@O @!