繁体   English   中英

Android上的相机应用

[英]Camera app on 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

部署的应用程序的屏幕截图

问题很可能是,尽管您已在清单中请求了“摄像机”权限,但您还需要在运行时询问。 原因是在较旧版本的Android(我认为<Android 6.0)中,您只需要在清单中声明权限。 但是,现在用户可以在安装应用程序后打开和关闭权限。 因此,现在应该在运行时检查是否拥有所需功能的权限。 如果没有,则应要求用户启用它。

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

如果这解决了您的问题,那么您需要找到代码以在应用打开后要求用户向您授予权限。 这样做的一个这样的方式是简单地在启动屏幕上,这表现在这里

我假设您在装有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'

此外,似乎您使用的是不推荐使用的camera API而不是camera2 API:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM