Камера не работает при первом запуске приложения после установки - PullRequest
0 голосов
/ 29 октября 2019

Я реализовал простой код QR-сканера в своем приложении для Android. Код работает нормально, но по какой-то причине при установке, когда вы впервые открываете приложение, CameraView остается черным. Только после второго запуска приложения оно работает (после закрытия onResume ничего не изменится)

Вот мой код:

private static Context context;

private CameraSource cameraSource;
private SurfaceView cameraView;
private final int MY_PERMISSIONS_REQUEST_CAMERA = 1;
private String token = "";
private String tokenanterior = "";
private static Activity mActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    context = this;
    mActivity = this;

    // verifico si el usuario dio los permisos para la camara
    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // verificamos la version de ANdroid que sea al menos la M para mostrar
            // el dialog de la solicitud de la camara
            if (shouldShowRequestPermissionRationale(
                    Manifest.permission.CAMERA)) ;
            requestPermissions(new String[]{Manifest.permission.CAMERA},
                    MY_PERMISSIONS_REQUEST_CAMERA);
        }
    }

    cameraView = (SurfaceView) findViewById(R.id.camera_view);
    initQR();

}

public void initQR() {

    // creo el detector qr
    BarcodeDetector barcodeDetector =
            new BarcodeDetector.Builder(this)
                    .setBarcodeFormats(Barcode.ALL_FORMATS)
                    .build();

    // creo la camara
    cameraSource = new CameraSource
            .Builder(this, barcodeDetector)
            .setRequestedPreviewSize(1600, 1024)
            .setAutoFocusEnabled(true) //you should add this feature
            .build();

    // listener de ciclo de vida de la camara
    cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            // verifico si el usuario dio los permisos para la camara
            if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    // verificamos la version de ANdroid que sea al menos la M para mostrar
                    // el dialog de la solicitud de la camara
                    if (shouldShowRequestPermissionRationale(
                            Manifest.permission.CAMERA)) ;
                    requestPermissions(new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);
                }
                return;
            }else {
                try {
                    cameraSource.start(cameraView.getHolder());
                } catch (IOException ie) {
                    Log.e("CAMERA SOURCE", ie.getMessage());
                }
            }
        }

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

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

    // preparo el detector de QR
    barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
        @Override
        public void release() {
        }
}

Любые идеи?

РЕДАКТИРОВАТЬ: После ответа @ r2rek я реализовал функцию onRequestPermissionResult () в классе следующим образом:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_CAMERA: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                Log.i("Results:", "HE GAVE EM");
                initQR();
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

    }
}

Но это не такЧтобы устранить проблему, initQR выполняется дважды (когда меня спрашивают о разрешении снимать видео и делать снимки). Но, тем не менее, при первой установке он не будет правильно отображать поток камеры на SurfaceView.

Ответы [ 3 ]

0 голосов
/ 29 октября 2019

Все просто. В первый раз вы запрашиваете разрешение, но не реагируете на разрешение пользователя. Во второй раз разрешение уже предоставлено. Вам необходимо реализовать onRequestPermissionResult в соответствии с приведенной ниже документацией:

https://developer.android.com/training/permissions/requesting#handle-response

В основном, когда пользователь позволяет вам использовать камеру, вам необходимо initQr()

0 голосов
/ 01 ноября 2019

В конечном итоге единственным решением было запросить разрешения в отдельном упражнении. Поскольку я хотел, чтобы действия с камерой были первыми, мне пришлось реализовать новое пустое действие, полностью для запроса разрешений, а затем для продолжения работы с камерой.

0 голосов
/ 29 октября 2019

Вы выполнили запрос на получение разрешения в манифесте? Важно разместить их помимо кода во время выполнения:

<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...