Issue
I've implemented a simple QR Scanner code in my Android App. The code seems to work fine but for some reason, upon installation, the first time you open the app, the CameraView remains black. It is only after the second time I start the app that it works (after closing, onResume won't change anything)
Here's my code:
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() {
}
}
Any ideas?
EDIT: Following @r2rek's answer, I implemented the onRequestPermissionResult() function in the class as follows:
@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;
}
}
}
But this didn't not fix the issue, initQR gets executed twice (as I get asked for permission to film video and to take pictures). But still, on first install it won't properly show the camera stream on the SurfaceView.
Solution
The only solution ended up being to ask for the permissions in a separate activity. As I wanted the camera activity to be the first, I had to implement a new blank activity, entirely for asking the permissions and then continuing to the camera activity.
Answered By - Manu Sisko