在我允许后,表面视图不显示相机

时间:2017-11-30 12:10:12

标签: android camera surfaceview runtime-permissions

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_camera, container, false);
    cameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    flipCamera = view.findViewById(R.id.flipCamera);
    flashCameraButton = view.findViewById(R.id.flash);
    captureImage = view.findViewById(R.id.captureImage);
    surfaceView = view.findViewById(R.id.surfaceView);
    surfaceHolder = surfaceView.getHolder();
    surfaceHolder.addCallback(this);
    flipCamera.setOnClickListener(this);
    captureImage.setOnClickListener(this);
    flashCameraButton.setOnClickListener(this);
    getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

    if (Camera.getNumberOfCameras() > 1) {
        flipCamera.setVisibility(View.VISIBLE);
    }
    if (!getActivity().getBaseContext().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH)) {
        flashCameraButton.setVisibility(View.GONE);
    }


    return view;
}

@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void surfaceCreated(SurfaceHolder holder) {

    if (!openCamera(Camera.CameraInfo.CAMERA_FACING_BACK)) {
        alertCameraDialog();
    }

}


private boolean openCamera(int id) {
    boolean result = false;
    cameraId = id;
    releaseCamera();
    try {
        camera = Camera.open(cameraId);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (camera != null) {
        try {
            setUpCamera(camera);
            camera.setErrorCallback(new Camera.ErrorCallback() {

                @Override
                public void onError(int error, Camera camera) {

                }
            });
            camera.setPreviewDisplay(surfaceHolder);
            camera.startPreview();
            result = true;
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
            releaseCamera();
        }
    }
    return result;
}

private void setUpCamera(Camera c) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, info);
    rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
    int degree = 0;
    switch (rotation) {
        case Surface.ROTATION_0:
            degree = 0;
            break;
        case Surface.ROTATION_90:
            degree = 90;
            break;
        case Surface.ROTATION_180:
            degree = 180;
            break;
        case Surface.ROTATION_270:
            degree = 270;
            break;

        default:
            break;
    }

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        // frontFacing
        rotation = (info.orientation + degree) % 330;
        rotation = (360 - rotation) % 360;
    } else {
        // Back-facing
        rotation = (info.orientation - degree + 360) % 360;
    }
    c.setDisplayOrientation(rotation);
    Camera.Parameters params = c.getParameters();

    showFlashButton(params);

    List<String> focusModes = params.getSupportedFlashModes();
    if (focusModes != null) {
        if (focusModes
                .contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            params.setFlashMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }
    }

    params.setRotation(rotation);
}

private void showFlashButton(Camera.Parameters params) {
    boolean showFlash = (getActivity().getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA_FLASH) && params.getFlashMode() != null)
            && params.getSupportedFlashModes() != null
            && params.getSupportedFocusModes().size() > 1;

    flashCameraButton.setVisibility(showFlash ? View.VISIBLE
            : View.INVISIBLE);

}

private void releaseCamera() {
    try {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.setErrorCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("error", e.toString());
        camera = null;
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
                           int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.flash:
            flashOnButton();
            break;
        case R.id.flipCamera:
            flipCamera();
            break;
        case R.id.captureImage:
            takeImage();
            break;

        default:
            break;
    }
}

private void takeImage() {
    camera.takePicture(null, null, new Camera.PictureCallback() {

        private File imageFile;

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                // convert byte array into bitmap
                Bitmap loadedImage = null;
                Bitmap rotatedBitmap = null;
                loadedImage = BitmapFactory.decodeByteArray(data, 0, data.length);

                // rotate Image
                Matrix rotateMatrix = new Matrix();
                rotateMatrix.postRotate(rotation);
                rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
                        loadedImage.getWidth(), loadedImage.getHeight(),
                        rotateMatrix, false);
                String state = Environment.getExternalStorageState();
                File folder = null;
                if (state.contains(Environment.MEDIA_MOUNTED)) {
                    folder = new File(Environment
                            .getExternalStorageDirectory() + "/Demo");
                } else {
                    folder = new File(Environment
                            .getExternalStorageDirectory() + "/Demo");
                }

                boolean success = true;
                if (!folder.exists()) {
                    success = folder.mkdirs();
                }
                if (success) {
                    java.util.Date date = new java.util.Date();
                    imageFile = new File(folder.getAbsolutePath()
                            + File.separator
                            + new Timestamp(date.getTime()).toString()
                            + "Image.jpg");

                    imageFile.createNewFile();
                    Toast.makeText(getActivity().getBaseContext(), "Image Saved", Toast.LENGTH_SHORT).show();
                    openCamera(cameraId);
                } else {
                    Toast.makeText(getActivity().getBaseContext(), "Image Not saved", Toast.LENGTH_SHORT).show();
                    return;
                }

                ByteArrayOutputStream ostream = new ByteArrayOutputStream();

                // save image into gallery
                rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);

                FileOutputStream fout = new FileOutputStream(imageFile);
                fout.write(ostream.toByteArray());
                fout.close();
                ContentValues values = new ContentValues();

                values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
                values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
                values.put(MediaStore.MediaColumns.DATA, imageFile.getAbsolutePath());
                getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

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

        }
    });

}


private void flipCamera() {
    int id = (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK ? Camera.CameraInfo.CAMERA_FACING_FRONT
            : Camera.CameraInfo.CAMERA_FACING_BACK);
    if (!openCamera(id)) {
        alertCameraDialog();
    }
}

private void alertCameraDialog() {
    Toast.makeText(getActivity(), "Error to open camera", Toast.LENGTH_SHORT).show();
}


private void flashOnButton() {
    if (camera != null) {
        try {
            Camera.Parameters param = camera.getParameters();
            param.setFlashMode(!flashmode ? Camera.Parameters.FLASH_MODE_TORCH
                    : Camera.Parameters.FLASH_MODE_OFF);
            camera.setParameters(param);
            flashmode = !flashmode;
        } catch (Exception e) {
            // TODO: handle exception
        }

    }
}

}

这是我的相机片段代码。当我在运行时给予权限时,surfaceview不会显示相机。它在onResume()或该片段中的任何Button单击时显示摄像头。如何解决此问题。如何设置当我在许可中单击允许按钮时,它会自动在表面视图中显示相机。

6 个答案:

答案 0 :(得分:1)

使用此课程

public class RunTimePermission extends Activity {

private Activity activity;
private ArrayList<PermissionBean> arrayListPermission;
private String[] arrayPermissions;
private RunTimePermissionListener runTimePermissionListener;

public RunTimePermission(Activity activity)
{
    this.activity = activity;
}

public class PermissionBean
{

    String permission;
    boolean isAccept;
}

public void requestPermission(String[] permissions, RunTimePermissionListener runTimePermissionListener)
{
    this.runTimePermissionListener = runTimePermissionListener;
    arrayListPermission = new ArrayList<PermissionBean>();


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    {
        for (int i = 0; i < permissions.length; i++)
        {
            PermissionBean permissionBean = new PermissionBean();
            if (ContextCompat.checkSelfPermission(activity, permissions[i]) == PackageManager.PERMISSION_GRANTED)
            {
                permissionBean.isAccept = true;
            }
            else
            {
                permissionBean.isAccept = false;
                permissionBean.permission = permissions[i];
                arrayListPermission.add(permissionBean);
            }


        }

        if (arrayListPermission.size() <= 0)
        {
            runTimePermissionListener.permissionGranted();
            return;
        }
        arrayPermissions = new String[arrayListPermission.size()];
        for (int i = 0; i < arrayListPermission.size(); i++)
        {
            arrayPermissions[i] = arrayListPermission.get(i).permission;
        }
        activity.requestPermissions(arrayPermissions, 10);
    }
    else
    {
        if (runTimePermissionListener != null)
        {
            runTimePermissionListener.permissionGranted();
        }
    }
}

public interface RunTimePermissionListener
{

    void permissionGranted();

    void permissionDenied();
}

private void callSettingActivity()
{
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
    intent.setData(uri);
    activity.startActivity(intent);

}

private void checkUpdate()
{
    boolean isGranted = true;
    int deniedCount = 0;
    for (int i = 0; i < arrayListPermission.size(); i++)
    {
        if (!arrayListPermission.get(i).isAccept)
        {
            isGranted = false;
            deniedCount++;
        }
    }

    if (isGranted)
    {
        if (runTimePermissionListener != null)
        {
            runTimePermissionListener.permissionGranted();
        }
    }
    else
    {
        if (runTimePermissionListener != null)
        {

            setAlertMessage();
            runTimePermissionListener.permissionDenied();
        }
    }
}

public void setAlertMessage()
{
    AlertDialog.Builder adb;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        adb = new AlertDialog.Builder(activity, android.R.style.Theme_Material_Light_Dialog_Alert);
    } else {
        adb = new AlertDialog.Builder(activity);
    }

    adb.setTitle(activity.getResources().getString(R.string.app_name));
    String msg = "<p>Dear User, </p>" +
            "<p>Seems like you have <b>\"Denied\"</b> the minimum requirement permission to access more features of application.</p>" +
            "<p>You must have to <b>\"Allow\"</b> all permission. We will not share your data with anyone else.</p>" +
            "<p>Do you want to enable all requirement permission ?</p>" +
            "<p>Go To : Settings >> App > " + activity.getResources().getString(R.string.app_name) + " Permission : Allow ALL</p>";

    adb.setMessage(Html.fromHtml(msg));
    adb.setPositiveButton("Allow All", new AlertDialog.OnClickListener()
    {

        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            callSettingActivity();
            dialog.dismiss();
        }
    });

    adb.setNegativeButton("Remind Me Later", new AlertDialog.OnClickListener()
    {

        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            dialog.dismiss();
        }
    });
    if (!((Activity) activity).isFinishing() && msg.length() > 0)
    {
        adb.show();
    }
    else
    {
        Log.v("log_tag", "either activity finish or message length is 0");
    }
}

private void updatePermissionResult(String permissions, int grantResults)
{

    for (int i = 0; i < arrayListPermission.size(); i++)
    {
        if (arrayListPermission.get(i).permission.equals(permissions))
        {
            if (grantResults == 0)
            {
                arrayListPermission.get(i).isAccept = true;
            }
            else
            {
                arrayListPermission.get(i).isAccept = false;
            }
            break;
        }
    }

}


public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
    for (int i = 0; i < permissions.length; i++)
    {
        updatePermissionResult(permissions[i], grantResults[i]);
    }
    checkUpdate();
}
}

将此代码写入您的活动onCreate()方法

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

    runTimePermission = new RunTimePermission(this);
    runTimePermission.requestPermission(new String[]{Manifest.permission.CAMERA,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    }, new RunTimePermission.RunTimePermissionListener() {

        @Override
        public void permissionGranted() {
            // First we need to check availability of play services
            initControls();

            identifyOrientationEvents();

            //create a folder to get image
            folder = new File(Environment.getExternalStorageDirectory() + "/Media");
            if (!folder.exists()) {
                folder.mkdirs();
            }
            //capture image on callback
            captureImageCallback();
            //
            if (camera != null) {
                Camera.CameraInfo info = new Camera.CameraInfo();
                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    imgFlashOnOff.setVisibility(View.GONE);
                }
            }
        }

        @Override
        public void permissionDenied() {
        }
    });

然后从onCreate()

中编写此代码
  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (runTimePermission != null) {
        runTimePermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

答案 1 :(得分:1)

在onCreate中,将surfaceView的可见性设置为“不可见”。

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    if (checkCameraHardware(this) == false) {
        showDialogForExit();
    }
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    surfaceView.setVisibility(View.INVISIBLE);
    infoTextview = (TextView) findViewById(R.id.info_text);
    askForPermissions();
}

然后将cameraSource附加到surfaceView之后,再次将surfaceView的可见性设置为VISIBLE。

        surfaceView.setVisibility(View.VISIBLE);

答案 2 :(得分:1)

很抱歉无法提供最新答案,但对某人可能有用。只需在 onRequestPermissionsResult 中调用启动摄像头方法,如下所示:

surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                cameraSource.start(surfaceView.getHolder());
                Utils.log(TAG, "Check permission: granted - start camera");
            } else {
                Utils.log(TAG, "Check permission: restricted - request");
                requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        cameraSource.stop();
    }
});

显示相机的默认方式如下:

server_path

答案 3 :(得分:1)

对我有用:

在获得许可或显示任何对话框之前,将表面可见性设置为消失

surfaceView.setVisibility(View.GONE);

然后在获得许可或关闭对话框后,将表面可见性设置为可见

surfaceView.setVisibility(View.VISIBLE);

答案 4 :(得分:0)

您必须在此处收到您的许可详情

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CAMERA_PERMISSION:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //Here call or Open your camera;
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

了解更多信息:

链接1:https://developer.android.com/training/permissions/requesting.html

链接2:https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/

答案 5 :(得分:0)

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE:
                for (int result : grantResults) {
                    if (result == PackageManager.PERMISSION_GRANTED) {
                        surfaceView.setVisibility(View.VISIBLE);    //   <----there u go
                        return;
                    } else {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                                Manifest.permission.CAMERA)) {

                        } else {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.CAMERA},
                                    CODE_REQUESTED_1);
                        }
                    }
                }

        }
    }