简体   繁体   English

Android上的相机应用

[英]Camera app on android

I am beginner in android developing and I am trying to make a camera app. 我是android开发的初学者,我正在尝试制作相机应用。 The camera app is opening but camera hardware is not detecting this is the code of main activity code. 摄像头应用正在打开,但摄像头硬件未检测到这是主要活动代码。 Now what am I missing to added to detect camera hardware please describe it and help me to solve it 现在我缺少要检测相机硬件的内容,请描述一下并帮助我解决

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

this is the manifest code 这是清单代码

<?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>

this is the logcat error 这是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 部署的应用程序的屏幕截图

The issue is most likely that, while you have asked for the Camera permission in the manifest, you also need to ask at runtime. 问题很可能是,尽管您已在清单中请求了“摄像机”权限,但您还需要在运行时询问。 The reason is that in older versions of Android (I think < Android 6.0), you only needed to declare permissions in the manifest. 原因是在较旧版本的Android(我认为<Android 6.0)中,您只需要在清单中声明权限。 However, now the user can turn permissions on and off after the app has been installed. 但是,现在用户可以在安装应用程序后打开和关闭权限。 So now you are supposed to check during runtime whether you have permission for the feature you require. 因此,现在应该在运行时检查是否拥有所需功能的权限。 If you don't have it, then you should ask the user to enable it. 如果没有,则应要求用户启用它。

You can find code for this online. 您可以在线找到此代码。 But first we need to verify that that is indeed the problem. 但是首先我们需要验证这确实是问题所在。 The simplest way of doing that is by going to your Android Settings app. 最简单的方法是转到“ Android Settings应用。 Then in there, there should be an Apps options. 然后在那里,应该有一个Apps选项。 Find your app and click on it. 找到您的应用程序,然后单击它。 In there, there should be a section with the Permissions. 在那里,应该有一个带有权限的部分。 If the camera permission is not checked there, then check it and rerun your app. 如果未在此处检查摄像头许可,请进行检查并重新运行您的应用。

If this fixes your issue, then you need to find code to ask the user to grant you the permission after the app opens. 如果这解决了您的问题,那么您需要找到代码以在应用打开后要求用户向您授予权限。 One such way of doing this is simply on the splash screen, as demonstrated here . 这样做的一个这样的方式是简单地在启动屏幕上,这表现在这里

I assume you are running the app on a device with Android 6 or higher. 我假设您在装有Android 6或更高版本的设备上运行该应用程序。 So, you should additionally check for the runtime permissions to use the camera: 因此,您还应该检查运行时权限以使用摄像机:

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

If you don't add this permission check, Android will block the access to the camera hardware. 如果您不添加此权限检查,Android将阻止对摄像头硬件的访问。 It will also block hardware detection, because it requires also the camera permission. 它也将阻止硬件检测,因为它还需要相机许可。 So, everytime you make a call on camera it will fail with a permission denied exception, which is logged in you logcat: 因此,每次在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'

Additionally, it seems you are using the deprecated camera api instead of the camera2 api: 此外,似乎您使用的是不推荐使用的camera API而不是camera2 API:

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

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

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