surface view does not show camera after i gave permission

☆樱花仙子☆ 提交于 2020-05-29 03:42:45

问题


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
        }

    }
}

}

This is my camera fragment code. When i give permission at runtime the surfaceview does not show camera. It show camera at onResume() or on any Button click in that fragment.How to solve this issue. How to set When i click on Allow button in permission it shows camera in surface view automatically.


回答1:


In onCreate set visibilty of surfaceView as INVISIBLE.

 @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();
}

Then after attaching cameraSource to surfaceView,set visibilty of surfaceView to VISIBLE again.

        surfaceView.setVisibility(View.VISIBLE);



回答2:


Use this class

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

Write this code in your activity onCreate() Method

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() {
        }
    });

then write this code out of 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);
}



回答3:


Sorry for late answer, but maybe it will be useful to someone. Just call start camera method in your onRequestPermissionsResult like this:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Utils.log(TAG, "onRequestPermissionsResult call");
    if (requestCode == REQUEST_CAMERA_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Utils.log(TAG, "Permission granted - show camera");
            if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                try {
                    cameraSource.start(surfaceView.getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

The default way to show camera might look like this:

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



回答4:


It worked for me:

before get permission or show any dialogs set surface visibility to GONE

surfaceView.setVisibility(View.GONE);

then after get permission or dismiss dialogs set surface visibility to VISIBLE

surfaceView.setVisibility(View.VISIBLE);



回答5:


you have to receive your permission details here

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

for more information :

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

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




回答6:


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

        }
    }


来源:https://stackoverflow.com/questions/47573182/surface-view-does-not-show-camera-after-i-gave-permission

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!