在Android 6.0中打开前置摄像头遇到麻烦

时间:2017-09-01 11:30:44

标签: java android camera android-6.0-marshmallow

See i have permissions for camera.打开前置摄像头返回null,即使我有使用摄像头的权限,搜索了很多答案但没有任何帮助 这就是我试图打开前置摄像头的方法

Camera cam = null;
try{
cam = Camera.open(1);
}catch (Exception e){
Log.e("Manojjjj", "Camera failed to open: " + e.getMessage());       
e.printStackTrace();
}
return cam;

代码在android 5中工作正常,但在android 6中,它为前置摄像头返回null(后置摄像头工作正常),当我将id更改为0时(cam = Camera.open(0)) ,它没有任何问题打开相机。 提前谢谢。

例外是:

09-01 16:52:29.228 24480-24480/com.magostech.dualcamera E/Manojjjj: Camera failed to open: Fail to connect to camera service

我搜索过的每个问题都说要添加运行时权限,但我已经给了运行时权限,所以我做得对,我认为我的问题不是添加运行时权限。

完整代码:

 private Camera mCamera = null;
private Camera mCamera1 = null;
private Handler mBackgroundHandler;
private CameraActivity mPreview;
private CameraPreview mPreview1;
FrameLayout preview;
FrameLayout preview1;
private static final int REQUEST_CAMERA_PERMISSION = 1;

public boolean safeToTakePicture = false;
String front,back;
Bitmap bitmap1;
Bitmap bitmap2;

private static final int PERMISSION_CALLBACK_CONSTANT = 100;
private static final int REQUEST_PERMISSION_SETTING = 101;
String[] permissionsRequired = new String[]{Manifest.permission.CAMERA,
        Manifest.permission.WRITE_EXTERNAL_STORAGE

        };
private SharedPreferences permissionStatus;
private boolean sentToSettings = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    permissionStatus = getSharedPreferences("permissionStatus",MODE_PRIVATE);
    checkForPermissions();
    // Create an instance of Camera


}

public void checkForPermissions(){
    if(ActivityCompat.checkSelfPermission(Main2Activity.this,permissionsRequired[0]) != PackageManager.PERMISSION_GRANTED
            ||ActivityCompat.checkSelfPermission(Main2Activity.this,permissionsRequired[1]) != PackageManager.PERMISSION_GRANTED){
        if(ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[0])
                ||ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[1])){
            AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
            builder.setTitle("Need Multiple Permissions");
            builder.setMessage("This app needs Camera and Location permissions.");
            builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                    ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            builder.show();
        }
        else if (permissionStatus.getBoolean(permissionsRequired[0],false)) {
            //Previously Permission Request was cancelled with 'Dont Ask Again',
            // Redirect to Settings after showing Information about why you need the permission
            AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
            builder.setTitle("Need Multiple Permissions");
            builder.setMessage("This app needs Camera and Location permissions.");
            builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                    sentToSettings = true;
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
                    Toast.makeText(getBaseContext(), "Go to Permissions to Grant  Camera and Location", Toast.LENGTH_LONG).show();
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            builder.show();
        }  else {
            //just request the permission
            ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
        }



        SharedPreferences.Editor editor = permissionStatus.edit();
        editor.putBoolean(permissionsRequired[0],true);
        editor.commit();
    } else {
        //You already have the permission, just go ahead.
        proceedAfterPermission();
    }


}


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode == PERMISSION_CALLBACK_CONSTANT){
        //check if all permissions are granted
        boolean allgranted = false;
        for(int i=0;i<grantResults.length;i++){
            if(grantResults[i]==PackageManager.PERMISSION_GRANTED){
                allgranted = true;
            } else {
                allgranted = false;
                break;
            }
        }

        if(allgranted){
            proceedAfterPermission();
        } else if(ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[0])
                || ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[1])
                || ActivityCompat.shouldShowRequestPermissionRationale(Main2Activity.this,permissionsRequired[2])){

            AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
            builder.setTitle("Need Multiple Permissions");
            builder.setMessage("This app needs Camera and Location permissions.");
            builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                    ActivityCompat.requestPermissions(Main2Activity.this,permissionsRequired,PERMISSION_CALLBACK_CONSTANT);
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            builder.show();
        } else {
            Toast.makeText(getBaseContext(),"Unable to get Permission",Toast.LENGTH_LONG).show();
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_PERMISSION_SETTING) {
        if (ActivityCompat.checkSelfPermission(Main2Activity.this, permissionsRequired[0]) == PackageManager.PERMISSION_GRANTED) {
            //Got Permission
            proceedAfterPermission();
        }
    }
}

private void proceedAfterPermission() {
    mCamera = getCameraInstance();
    mCamera1 = openFrontFacingCamera();
    // Create our Preview view and set it as the content of our activity.

        mPreview = new CameraActivity(this, mCamera);
        mPreview1 = new CameraPreview(this,mCamera1);
        preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview1 =(FrameLayout) findViewById(R.id.camera_preview1);
        preview.addView(mPreview);
        preview1.addView(mPreview1);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.take_picture);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (safeToTakePicture) {
                mCamera.takePicture(null,null,backCamera);
                mCamera1.takePicture(null, null, frontCamera);
                safeToTakePicture = false;
            }
        }
    });

}


public static Camera getCameraInstance(){
    Camera c = null;

    try {
        c = Camera.open(0); // attempt to get a Camera instance

    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}


private Camera openFrontFacingCamera(){
    int cameraCount = 0;

    Camera cam = null;

    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 {
                Log.e("Cam Id",String.valueOf(camIdx));
                cam = Camera.open( camIdx );
            } catch (RuntimeException e) {
                e.printStackTrace();
                Log.e("Manoj", "Camera failed to open: " );
            }
        }
    }

    return cam;
}



@Override
protected void onPostResume() {
    super.onPostResume();
    if (sentToSettings) {
        if (ActivityCompat.checkSelfPermission(Main2Activity.this, permissionsRequired[0]) == PackageManager.PERMISSION_GRANTED) {
            //Got Permission
            proceedAfterPermission();
        }
    }
}


private Camera.PictureCallback frontCamera = new Camera.PictureCallback() {


    @Override
    public void onPictureTaken(final byte[] data, Camera camera) {

        camera.startPreview();
        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/Dual Camera");

        if (myDir.exists()) {
            myDir.delete();
        }
        myDir.mkdirs();

        String fname = "Image" + new Date().getTime() + ".jpg";

        File file = new File(myDir, fname);


        try{
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();

            MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);

            front = String.valueOf(file);
            bitmap1 = BitmapFactory.decodeFile(front);
            Log.e("Front",front);


            if(bitmap1!=null&&bitmap2!=null){
                mergeBitmap(bitmap1,bitmap2);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        safeToTakePicture = true;
    }



};


public Bitmap mergeBitmap(Bitmap bitmap1, Bitmap bitmap2) {
    Bitmap mergedBitmap = null;

    int w, h = 0;

    h = bitmap1.getHeight() + bitmap2.getHeight();
    if (bitmap1.getWidth() > bitmap2.getWidth()) {
        w = bitmap1.getWidth();
    } else {
        w = bitmap2.getWidth();
    }

    mergedBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(mergedBitmap);

    canvas.drawBitmap(bitmap1, 0f, 0f, null);
    canvas.drawBitmap(bitmap2, 0f, bitmap1.getHeight(), null);

    saveBitmap(mergedBitmap);
    return mergedBitmap;
}

private Camera.PictureCallback backCamera = new Camera.PictureCallback() {


    @Override
    public void onPictureTaken(final byte[] data, Camera camera) {

        camera.startPreview();
        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/Dual Camera");

        if (myDir.exists()) {
            myDir.delete();
        }
        myDir.mkdirs();

        String fname = "Image" + new Date().getTime() + ".jpg";

        File file = new File(myDir, fname);



        try{
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();

            MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);

            back = String.valueOf(file);
            bitmap2 = BitmapFactory.decodeFile(String.valueOf(file));
            Log.e("Back",back);


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        safeToTakePicture = true;
    }



};

private void saveBitmap(Bitmap finalBitmap){
    String root = Environment.getExternalStorageDirectory().toString();
    File myDir = new File(root + "/Dual Camera");

    if (myDir.exists()) {
        myDir.delete();
    }
    myDir.mkdirs();

    String fname = "Merged" + new Date().getTime() + ".jpg";

    File file = new File(myDir, fname);

    try{
        FileOutputStream fos = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
        fos.flush();
        fos.close();

        MediaScannerConnection.scanFile(Main2Activity.this, new String[]{file.getPath()}, new String[]{"image/jpeg"}, null);
        Toast.makeText(getApplicationContext(),
                "Image Saved to:" + file, Toast.LENGTH_LONG).show();


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

@Override
protected void onResume() {
    super.onResume();
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED) {
        try {
            mCamera = Camera.open(0);
            mCamera.setPreviewCallback(null);
            mPreview = new CameraActivity(Main2Activity.this, mCamera);
            preview.addView(mPreview);
            mCamera.startPreview();

        }catch (Exception e) {
            Log.d("Manoj", "Error starting camera preview: " + e.getMessage());
        }try{
            if (mCamera1 == null){
                mCamera1 = openFrontFacingCamera();
                //mCamera1 = Camera.open(1);
                mCamera1.setPreviewCallback(null);
                mPreview1 = new CameraPreview(Main2Activity.this,mCamera1);
                preview1.addView(mPreview1);
                mCamera1.startPreview();
            }
        }catch (Exception e){
            Log.d("Manoj", "Error starting camera preview: " + e.getMessage());
        }
        safeToTakePicture = true;
    }
     else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                REQUEST_CAMERA_PERMISSION);
    }
}
@Override
protected void onPause() {

    try {
        // release the camera immediately on pause event
        // releaseCamera();
        mCamera1.stopPreview();
        mCamera1.setPreviewCallback(null);
        mPreview1.getHolder().removeCallback(mPreview1);
        mCamera1.release();
        mCamera1 = null;

    } catch (Exception e) {
        e.printStackTrace();
    }

    try{
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mPreview.getHolder().removeCallback(mPreview);
        mCamera.release();
        mCamera = null;
    }catch (Exception e){
        e.printStackTrace();
    }
    super.onPause();
}
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mBackgroundHandler != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            mBackgroundHandler.getLooper().quitSafely();
        } else {
            mBackgroundHandler.getLooper().quit();
        }
        mBackgroundHandler = null;
    }
}



@Override
public void onBackPressed(){
    super.onBackPressed();
}

2 个答案:

答案 0 :(得分:0)

试试这个:

 if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{android.Manifest.permission.CAMERA}, 5);
    }
}

使用 Ctrl + O 复制覆盖以下方法,粘贴可能会导致错误

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 5) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Now user should be able to use camera
        }
        else {
            // Your app will not have this permission. Turn off all functions
            // that require this permission or it will force close like your
            // original question
        }
    }
}

答案 1 :(得分:0)

根据Android Doc,Android应用程序在流程沙箱中运行。 对于Android 6.0或更高版本的操作系统,用户无法访问基本沙箱未提供的其他功能。您需要先申请 PERMISSION 。以下是那些重要的PERMISSIONS

如果设备运行Android 5.1(API级别22)或更低版本,或者应用程序的targetSdkVersion为22或更低,系统会要求用户在安装时授予权限,您可以访问任何敏感工具。

查看DOC了解更多详情。