Android上的相机应用程序

时间:2018-04-26 05:54:35

标签: java android

我是android开发的初学者,我正在尝试制作相机应用程序。相机应用程序正在打开,但相机硬件未检测到这是主要活动代码的代码。现在我想要添加什么来检测相机硬件,请描述它并帮助我解决它

public class CamTestActivity extends Activity {
    private static final String TAG = "CamTestActivity";
    Preview preview;
    Button buttonClick;
    Camera camera;
    Activity act;
    Context ctx;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ctx = this;
        act = this;
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.main);

        preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
        preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        ((FrameLayout) findViewById(R.id.layout)).addView(preview);
        preview.setKeepScreenOn(true);

        preview.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                camera.takePicture(shutterCallback, rawCallback, jpegCallback);
            }
        });

        Toast.makeText(ctx, getString(R.string.take_photo_help), Toast.LENGTH_LONG).show();

        buttonClick = (Button) findViewById(R.id.btnCapture);

        buttonClick.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                try {
                    preview.mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
                    camera.takePicture(shutterCallback, rawCallback, jpegCallback);
                }catch (Exception e)
                {
                    Toast.makeText(ctx, getString(R.string.camera_not_found), Toast.LENGTH_LONG).show();
                }
            }
        });

        buttonClick.setOnLongClickListener(new OnLongClickListener(){
            @Override
            public boolean onLongClick(View arg0) {
                camera.autoFocus(new Camera.AutoFocusCallback(){
                    @Override
                    public void onAutoFocus(boolean arg0, Camera arg1) {
                        //camera.takePicture(shutterCallback, rawCallback, jpegCallback);
                    }
                });
                return true;
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        int numCams = Camera.getNumberOfCameras();
        if(numCams > 0){
            try{
                camera = Camera.open(1);
                camera.startPreview();
                preview.setCamera(camera);
            } catch (RuntimeException ex){
                Toast.makeText(ctx, getString(R.string.camera_not_found), Toast.LENGTH_LONG).show();
            }
        }
    }

    @Override
    protected void onPause() {
        if(camera != null) {
            camera.stopPreview();
            preview.setCamera(null);
            camera.release();
            camera = null;
        }
        super.onPause();
    }

    private void resetCam() {
        camera.startPreview();
        preview.setCamera(camera);
    }

    private void refreshGallery(File file) {
        Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(Uri.fromFile(file));
        sendBroadcast(mediaScanIntent);
    }

    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");
        }
    };

    PictureCallback jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            new SaveImageTask().execute(data);
            resetCam();
            Log.d(TAG, "onPictureTaken - jpeg");
        }
    };

    private class SaveImageTask extends AsyncTask<byte[], Void, Void> {

        @Override
        protected Void doInBackground(byte[]... data) {
            FileOutputStream outStream = null;

            // Write to SD Card
            try {
                File sdCard = Environment.getExternalStorageDirectory();
                File dir = new File (sdCard.getAbsolutePath() + "/camtest");
                dir.mkdirs();

                String fileName = String.format("%d.jpg", System.currentTimeMillis());
                File outFile = new File(dir, fileName);

                outStream = new FileOutputStream(outFile);
                outStream.write(data[0]);
                outStream.flush();
                outStream.close();

                Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());

                refreshGallery(outFile);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            return null;
        }
        }
}

这是清单代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.niit.cameraapp">
    <uses-sdk android:minSdkVersion="9" />

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

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".CamTestActivity"
            android:screenOrientation="portrait" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这是logcat错误

04-26 12:20:13.694 9167-9167/com.example.niit.cameraapp I/zygote64: Late-enabling -Xcheck:jni
04-26 12:20:13.969 9167-9167/com.example.niit.cameraapp I/InstantRun: starting instant run server: is main process
04-26 12:20:14.142 9167-9167/com.example.niit.cameraapp W/.niit.cameraapp: type=1400 audit(0.0:84362): avc: denied { read } for name="u:object_r:camera_prop:s0" dev="tmpfs" ino=6271 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:camera_prop:s0 tclass=file permissive=0
04-26 12:20:14.149 9167-9167/com.example.niit.cameraapp E/libc: Access denied finding property "camera.hal1.packagelist"
04-26 12:20:14.152 9167-9167/com.example.niit.cameraapp W/CameraBase: An error occurred while connecting to camera 1: Status(-8): '1: validateClientPermissionsLocked:920: Caller "com.example.niit.cameraapp" (PID 10190, UID 9167) cannot open camera "1" without camera permission'
04-26 12:20:14.181 9167-9330/com.example.niit.cameraapp D/OpenGLRenderer: HWUI GL Pipeline
04-26 12:20:14.233 9167-9330/com.example.niit.cameraapp I/Adreno: QUALCOMM build                   : 7f08991, I8a9bdcf8d3
04-26 12:20:14.236 9167-9330/com.example.niit.cameraapp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8953.so from the current namespace instead.
04-26 12:20:14.232 9167-9167/com.example.niit.cameraapp W/RenderThread: type=1400 audit(0.0:84363): avc: denied { search } for name="proc" dev="debugfs" ino=5174 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0
04-26 12:20:14.244 9167-9330/com.example.niit.cameraapp I/Adreno: PFP: 0x005ff087, ME: 0x005ff063
04-26 12:20:14.249 9167-9330/com.example.niit.cameraapp I/OpenGLRenderer: Initialized EGL, version 1.4
04-26 12:20:14.249 9167-9330/com.example.niit.cameraapp D/OpenGLRenderer: Swap behavior 2
04-26 12:20:14.309 9167-9330/com.example.niit.cameraapp I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib64/hw/gralloc.msm8953.so from the current namespace instead.
04-26 12:20:17.316 9167-9202/com.example.niit.cameraapp I/zygote64: Debugger is no longer active

screenshot of the deployed app

2 个答案:

答案 0 :(得分:1)

问题很可能是,虽然您已在清单中询问了Camera权限,但您还需要在运行时询问。原因是在旧版Android(我认为&lt; Android 6.0)中,您只需要在清单中声明权限。但是,现在用户可以在安装应用程序后打开和关闭权限。因此,现在您应该在运行时检查您是否拥有所需功能的权限。如果您没有,那么您应该要求用户启用它。

您可以在线找到此代码。但首先我们需要验证这确实是问题所在。最简单的方法是转到Android Settings应用。然后在那里,应该有Apps个选项。找到您的应用并点击它。在那里,应该有一个带有权限的部分。如果未在此处检查相机权限,请检查并重新运行您的应用。

如果这样可以解决您的问题,那么您需要找到代码,要求用户在应用打开后向您授予权限。这样做的一种方法就是在启动画面上,如here所示。

答案 1 :(得分:1)

我假设您在使用Android 6或更高版本的设备上运行该应用。因此,您还应检查使用相机的运行时权限:

https://developer.android.com/training/permissions/requesting

如果您不添加此权限检查,Android将阻止访问相机硬件。它还会阻止硬件检测,因为它还需要相机权限。因此,每当您在camera上进行呼叫时,它都将失败并显示一个权限被拒绝的异常,该异常会记录在您的logcat中:

04-26 12:20:14.152 9167-9167/com.example.niit.cameraapp W/CameraBase: An error occurred while connecting to camera 1: Status(-8): '1: validateClientPermissionsLocked:920: Caller "com.example.niit.cameraapp" (PID 10190, UID 9167) cannot open camera "1" without camera permission'

此外,您似乎正在使用弃用的相机api而不是camera2 api:

https://developer.android.com/reference/android/hardware/camera2/package-summary