Android 4.3.1:在服务中拍照

时间:2013-12-20 15:29:01

标签: android image service camera

我正在开发一个开源设备管理器,但是有一个安全功能的问题,如果手机被盗,用户可以从相机拍照。在模拟器中一切都运行良好,但在运行Android 4.3.1的Nexus 4上,我收到以下错误(包括调试打印输出):

    12-20 10:05:28.083: D/HelperService(22358): HERE0
    12-20 10:05:28.354: D/HelperService(22358): HEREA
    12-20 10:05:28.354: D/HelperService(22358): HEREB
    12-20 10:05:28.374: D/HelperService(22358): HEREC
    12-20 10:05:28.374: D/HelperService(22358): HERED
    12-20 10:05:28.644: D/HelperService(22358): HERE2
    12-20 10:05:28.644: D/HelperService(22358): HERE11
    12-20 10:05:28.654: I/Choreographer(22358): Skipped 33 frames!  The application may be doing too much work on its main thread.
    12-20 10:05:30.656: D/AndroidRuntime(22358): Shutting down VM
    12-20 10:05:30.656: W/dalvikvm(22358): threadid=1: thread exiting with uncaught exception (group=0x416287c0)
    12-20 10:05:30.676: E/AndroidRuntime(22358): FATAL EXCEPTION: main
    12-20 10:05:30.676: E/AndroidRuntime(22358): java.lang.RuntimeException: takePicture failed
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.hardware.Camera.native_takePicture(Native Method)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.hardware.Camera.takePicture(Camera.java:1145)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.hardware.Camera.takePicture(Camera.java:1090)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at com.nowsci.odm.HelperService$2$1.run(HelperService.java:271)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.os.Handler.handleCallback(Handler.java:730)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.os.Handler.dispatchMessage(Handler.java:92)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.os.Looper.loop(Looper.java:137)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at android.app.ActivityThread.main(ActivityThread.java:5289)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at java.lang.reflect.Method.invokeNative(Native Method)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at java.lang.reflect.Method.invoke(Method.java:525)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
    12-20 10:05:30.676: E/AndroidRuntime(22358):    at dalvik.system.NativeStart.main(Native Method)

以下是代码。我知道这有点难看,但我一直试图让这个工作与统一尝试/捕获,巩固相机打开等等。

    public class HelperService extends Service {

    ...

        private SurfaceHolder sHolder;
        private Camera mCamera;
        private Parameters parameters;

        ...

        // For API 14 and newer
        public class CamCallback implements Camera.PreviewCallback {
            public void onPreviewFrame(byte[] data, Camera camera) {
                Log.d(TAG,"HERE1");
                /*
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mCamera.takePicture(null, null, mCall);
                        //camera.takePicture(null, null, mCall);
                    }
                }, 2000);
                */
            }
        }

        ...

        private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {

        ...

            public void onReceive(Context context, Intent intent) {

                ...

                if (message.equals("Command:FrontPhoto") || message.equals("Command:RearPhoto")) {
                    boolean cont = true;
                    if (message.equals("Command:RearPhoto")) {
                        Log.d(TAG,"HERE0");
                        try {
                            mCamera = Camera.open();
                        } catch (RuntimeException e) {
                        Log.d(TAG, e.getMessage());
                        cont = false;
                        } finally {
                        if (mCamera != null) {
                                Log.d(TAG,"HEREA");
                            mCamera.stopPreview();
                                Log.d(TAG,"HEREB");
                            mCamera.release();
                                Log.d(TAG,"HEREC");
                            mCamera = null;
                                Log.d(TAG,"HERED");
                        }
                        }
                        try {
                            mCamera = Camera.open();
                        } catch (RuntimeException e) {
                        Log.d(TAG, e.getMessage());
                        cont = false;
                        }
                    } else {
                        int cameraCount = 0;
                        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
                        cameraCount = Camera.getNumberOfCameras();
                        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
                            Camera.getCameraInfo(camIdx, cameraInfo);
                            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                                try {
                                    mCamera = Camera.open(camIdx);
                                } catch (RuntimeException e) {
                                Log.d(TAG, e.getMessage());
                                cont = false;
                                } finally {
                                if (mCamera != null) {
                                    mCamera.stopPreview();
                                    mCamera.release();
                                    mCamera = null;
                                }
                                }
                                try {
                                    mCamera = Camera.open(camIdx);
                                } catch (RuntimeException e) {
                                Log.d(TAG, e.getMessage());
                                cont = false;
                                }
                            }
                        }
                    }
                    if (cont) {
                        if (android.os.Build.VERSION.SDK_INT >= 14) {
                            Log.d(TAG,"HERE2");
                            CamPreview camPreview = new CamPreview(context, mCamera);
                            camPreview.setSurfaceTextureListener(camPreview);
                            CamCallback camCallback = new CamCallback();
                            mCamera.setPreviewCallback(camCallback);
                            mCamera.startPreview();
                            Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    mCamera.takePicture(null, null, mCall);
                                    Log.d(TAG,"HERE12");
                                }
                            }, 2000);
                            Log.d(TAG,"HERE11");
                        } else {
                            // Pre-android 4.0
                            Log.d(TAG,"HERE3");
                            SurfaceView sv = new SurfaceView(context);
                            sHolder = sv.getHolder();
                            sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
                            try {
                                mCamera.setPreviewDisplay(sHolder);
                                parameters = mCamera.getParameters();
                                mCamera.setParameters(parameters);
                                mCamera.startPreview();
                                Handler handler = new Handler();
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        mCamera.takePicture(null, null, mCall);
                                    }
                                }, 2000);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                ...

上面的违规代码是:

    Log.d(TAG,"HERE2");
    CamPreview camPreview = new CamPreview(context, mCamera);
    camPreview.setSurfaceTextureListener(camPreview);
    CamCallback camCallback = new CamCallback();
    mCamera.setPreviewCallback(camCallback);
    mCamera.startPreview();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            mCamera.takePicture(null, null, mCall);
            Log.d(TAG,"HERE12");
        }
    }, 2000);
    Log.d(TAG,"HERE11");

我在StackOverflow上发现这是另一个解决方案,用于在Android 4.0及更高版本的服务中拍照(大多数解决方案都集中在4.0之前的版本)。如上所述,在模拟器中工作正常,但在设备上无效。清单包括预期的:

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.front" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

想法?

感谢。

0 个答案:

没有答案