RedApparat / Fotoapparat

Making Camera for Android more friendly. 📸
Apache License 2.0
3.82k stars 405 forks source link

After the permissions questions accepted the preview is not working #328

Closed victorjaviermartin closed 5 years ago

victorjaviermartin commented 5 years ago

Hi, after the permission question accepted, the preview is not working, the next time that I enter, then the preview works.

Fragment loaded in landscape mode `public class UpdateDniFragment extends Fragment implements Runnable {

@BindView(R.id.cameraView)
CameraView cameraView;
@BindView(R.id.focusView)
FocusView focusView;
@BindView(R.id.capture)
View capture;
@BindView(R.id.function)
TextView function;
@BindView(R.id.close_capture)
ImageView ivCloseCapture;

Unbinder mUnbinder;
UpdateDniFragmentHelper helper;
private Handler _handler = new Handler();

private View mainFrame;

public UpdateDniFragment(){
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_update_dni, container, false);
    BusProvider.getInstance().register(this);
    mUnbinder = ButterKnife.bind(this, view);
    mainFrame = Objects.requireNonNull(getActivity()).findViewById(R.id.container_fragments);
    helper = new UpdateDniFragmentHelper(this);
    onBackPressed(view);
    return view;
}

@Override
public void onStart() {
    super.onStart();
    tabbarHide();
    try {
        if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);   // Rotamos antes de continuar
        }
        run();
    }catch (NullPointerException e){
        e.printStackTrace();
    }
    registerSystemUiVisibility();

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (helper.hasCameraPermission()) {
                helper.getCameraReference().updateConfiguration(helper.getCameraConfiguration());
                helper.getCameraReference().start();
            }
        }
    }, 60);
}

@Override
public void onStop() {

    if (helper.hasCameraPermission()) {
        helper.getCameraReference().stop();
    }

    unregisterSystemUiVisibility();
    //exitFullscreen(getActivity());
    _handler.removeCallbacks(this);
    super.onStop();
}

@Override
public void onResume() {
    super.onResume();
    tabbarHide();
    try {
        if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);   // Rotamos antes de continuar
        }
        run();
    }catch (NullPointerException e){
        e.printStackTrace();
    }

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (helper.hasCameraPermission()) {
                helper.getCameraReference().updateConfiguration(helper.getCameraConfiguration());
                helper.getCameraReference().start();
            }
        }
    }, 60);
}

@Override
public void onPause() {
    try {
        if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);    // Rotamos de vuelta
        }
        //exitFullscreen(getActivity());
    }catch (NullPointerException e){
        e.printStackTrace();
    }
    super.onPause();
}

@Override
public void onDestroy() {
    if(Objects.requireNonNull(getActivity()).getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
        getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);    // Rotamos de vuelta
    }
    //unregisterSystemUiVisibility();
    //exitFullscreen(getActivity());
    mUnbinder.unbind();
    BusProvider.getInstance().unregister(this);
    super.onDestroy();
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.e("REQPER", "" + requestCode + ", " + Arrays.toString(permissions) + ", " + Arrays.toString(grantResults));
    if (helper.getPermissionsDelegate().resultGranted(requestCode, permissions, grantResults)) {
        Log.e("REQPERIF", "" + requestCode + ", " + Arrays.toString(permissions) + ", " + Arrays.toString(grantResults));

        helper.setHasCameraPermission(true);
        Handler handler = new Handler();
        handler.postDelayed(() -> {
            if (helper.hasCameraPermission()) {
                helper.getCameraReference().updateConfiguration(helper.getCameraConfiguration());
                helper.getCameraReference().start();
            }
        }, 60);
        cameraView.setVisibility(View.VISIBLE);
    }
}

public static class MediolanumFrameProcessor implements FrameProcessor {
    @Override
    public void process(@NotNull Frame frame) {
        // Perform frame processing, if needed
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {

    super.onConfigurationChanged(newConfig);
    int currentOrientation = getResources().getConfiguration().orientation;

    if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE){
        Log.v("TAG","Landscape !!!");
        tabbarHide();
    }
    else {
        Log.v("TAG","Portrait !!!");
        tabbarHide();
    }
}

private void onBackPressed(View view){

    view.setFocusableInTouchMode(true);
    view.requestFocus();
    view.setOnKeyListener((v, keyCode, event) -> {
        if( keyCode == KeyEvent.KEYCODE_BACK )
        {
            CordovaNativeToHybridHelper helperNatToHyb = new CordovaNativeToHybridHelper(getActivity(), helper.getWebViewIdToAttack());
            helperNatToHyb.requestNormalKO(null, helper.getFunctionKO());
            Objects.requireNonNull(getActivity()).runOnUiThread(() -> getActivity().onBackPressed());
            return true;
        }
        return false;
    });

}

private void tabbarHide(){
    if (getActivity() instanceof ClientActivity) {
        ((ClientActivity) getActivity()).refreshTabBarButtonStates(null, null);
        ((ClientActivity) getActivity()).setTabBarVisibility("false");
    }
}

public static boolean isImmersiveAvailable() {
    return true;
}

public void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus) {
        _handler.removeCallbacks(this);
        _handler.postDelayed(this, 300);
    } else {
        _handler.removeCallbacks(this);
    }
}

public void onKeyDown(int keyCode) {
    if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
        _handler.removeCallbacks(this);
        _handler.postDelayed(this, 500);
    }
}

@Override
public void run() {
    setFullscreen();
}

public void setFullscreen() {
    setFullscreen(getActivity());
}

public void setFullscreen(Activity activity) {
    int flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN;

    if (isImmersiveAvailable()) {
        flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    }

    activity.getWindow().getDecorView().setSystemUiVisibility(flags);
}

public void exitFullscreen(Activity activity) {
    activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}

private void registerSystemUiVisibility() {
    final View decorView = Objects.requireNonNull(getActivity()).getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(visibility -> {
        if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
            setFullscreen();
        }
    });
}

private void unregisterSystemUiVisibility() {
    final View decorView = Objects.requireNonNull(getActivity()).getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener(null);
}

/**
 * METHODS
 */

public CameraView getCameraView() {
    return cameraView;
}

public FocusView getFocusView() {
    return focusView;
}

@OnClick(R.id.capture)
public void capturePhoto(){
    helper.takePicture(getActivity());
}

@OnClick(R.id.close_capture)
public void closeCapture(){
    CordovaNativeToHybridHelper helperNatToHyb = new CordovaNativeToHybridHelper(getActivity(), helper.getWebViewIdToAttack());
    helperNatToHyb.requestNormalKO(null, helper.getFunctionKO());
    Objects.requireNonNull(getActivity()).runOnUiThread(() -> getActivity().onBackPressed());
}

public void updateFunctionMessage(String text){
    function.setText(text);
    function.invalidate();
}

@Subscribe
public void onCardResultEventReceived(CardResultEvent event){
    if(event.isFront()){
        Log.e("Result", event.getVerifyIdCardResult().toString());
    }else{
        Log.e("Result", event.getVerifyIdCardResult().toString());
    }
}

} `

rodrigovenancio commented 5 years ago

Try using ViewStub! I did it and it worked. Sample:

activity_camera.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/parentLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".CNHScanActivity">

    <ViewStub
            android:id="@+id/camera_stub"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout="@layout/camera_view"
            android:visibility="gone"/>
</RelativeLayout>

camera_view.xml

<?xml version="1.0" encoding="utf-8"?>
<io.fotoapparat.view.CameraView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/camera_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Part of setup code in the activity:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Set Activity's layout
        setContentView(R.layout.activity_camera)

        // Check camera permission
        if (ActivityCompat.checkSelfPermission(
                context!!,
                Manifest.permission.CAMERA
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            setUpCamera()
        } else {
            requestCameraPermission()
        }
    }

private fun setUpCamera() {
        camera_stub.inflate()

        fotoapparat = Fotoapparat(
            context = context!!,
            view = camera_view,
            scaleType = ScaleType.CenterCrop,
            lensPosition = activeCamera.lensPosition,
            cameraConfiguration = activeCamera.configuration,
            logger = loggers(
                logcat()
            )
        )

        fotoapparat.start()
    }

private fun requestCameraPermission() {
        if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
            Snackbar.make(
                parentLayout, getString(R.string.permission_camera_explanation_cnh),
                Snackbar.LENGTH_INDEFINITE).setAction(
                "OK") {
                requestPermissions(arrayOf(Manifest.permission.CAMERA),
                    PERMISSION_REQUEST_CAMERA
                )
            }
                .show()
        } else {
            requestPermissions(arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode != PERMISSION_REQUEST_CAMERA) {
            return
        }

        if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            setUpCamera()
 }
    }
dmitry-zaitsev commented 5 years ago

Sorry for the late reply, it looks like issue is resolved so I am closing this.

p-fischer commented 5 years ago

The ViewStub approach worked for me. Thanks @rodrigovenancio However, this still feels like a workaround.

To make things easier, it would be nice to let Fotoapparat check for the permission automatically or to add a function onPermissionGranted() to be called in that scenario.