0

Im trying to get a QR scanner in a Fragment, so when it scans it shows a box so the user can visit the link or cancel it. So far the page loads but its blank white not displaying no QR Reader/Scanner

I have tried without success the ZXingScannerView and multiple changes and different websites but I keep missing something, Im quiet new in android so Im not really sure.

public class QRScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
    private ZXingScannerView mScannerView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_qr_scanner, container, false);
        mScannerView = new ZXingScannerView(getActivity());
        mScannerView.setResultHandler(QRScannerFragment.this); // Register ourselves as a
        mScannerView.startCamera();
        return mScannerView;

    }

    @Override
    public void onResume() {
        super.onResume();
        mScannerView.setResultHandler(this);
        mScannerView.startCamera();
    }

    @Override
    public void handleResult(Result rawResult) {
        Toast.makeText(getActivity(), "Contents = " + rawResult.getText() +
                ", Format = " + rawResult.getBarcodeFormat().toString(), Toast.LENGTH_SHORT).show();
        // Note:
        // * Wait 2 seconds to resume the preview.
        // * On older devices continuously stopping and resuming camera preview can result in freezing the app.
        // * I don't know why this is the case but I don't have the time to figure out.
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScannerView.resumeCameraPreview(QRScannerFragment.this);
            }
        }, 2000);
    }

    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();
    }
}

XML File

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">



</LinearLayout>

Maria
  • 41
  • 6
  • You're not currently using the layout, so you can remove the `View v = inflater...` line. Apart from that, how are you loading that `Fragment` into your `Activity`? Also, have you listed the `CAMERA` permission in your manifest. Have you requested it at runtime? – Mike M. Apr 12 '19 at 02:45
  • I have listed it on the manifest, but do I need it on runtime, plus how can I do that. And in term of loading it I have a fragment_qr_scanner in which I would like to load into @MikeM. – Maria Apr 12 '19 at 02:47
  • Yeah, `CAMERA` is a dangerous permission, so you have to request it at runtime on Marshmallow and above, if your `targetSdkVersion` is 23+, which is pretty much the case for most apps, these days. There are some examples [here](https://stackoverflow.com/q/38552144) and [here](https://stackoverflow.com/q/32635704), but if you'd like to, you can manually grant that permission to your app in the device Settings, after installation, so you can focus on the current issue, before you tackle the runtime permission request. I'm not clear on how exactly you're loading that `Fragment`, though. – Mike M. Apr 12 '19 at 02:53

1 Answers1

0

a bit late, for your scanner fragment

 @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (LOG_DEBUG) Log.w(TAG, "onCreateView: ");
    initScannerView();
    return mScannerView;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Log.e(TAG, "onViewCreated: ");

    mScannerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.w(TAG, "onClick: DO NOTHING");
        }
    });
    mScannerView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            Log.w(TAG, "onLongCLick: DO NOTHING");
            return true;
        }
    });

}

@Override
public void handleResult(Result rawResult) {
    Log.d(TAG, "handleResult: ");
    handleScanResult(rawResult);
}

@Override
public void onStart() {
    super.onStart();
    initScannerView();
}

@Override
public void onResume() {
    super.onResume();
    Log.e(TAG, "onResume: ");
    if (mScannerView != null) {
        mScannerView.setResultHandler(this);
        mScannerView.startCamera();
    }
}

@Override
public void onStop() {
    super.onStop();
    if (mScannerView != null) {
        mScannerView.setResultHandler(null);
        mScannerView.stopCamera();
    }
}



private void initScannerView() {
    if (mScannerView == null) {
        mScannerView = new ZXingScannerView(this.getContext());
    }
}

private void handleScanResult(Result rawResult) {
    if (rawResult != null) {
        mScanStringResult = rawResult.toString();
        Log.d(TAG, "handleResult - string result : " + mScanStringResult);
        Log.d(TAG, "handleResult - CODE FORMAT : " + rawResult.getBarcodeFormat().toString());
    }
}

you need to grant camera permission, Before doing a transaction of your Scan fragment, use initRequest() method.

   @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (LOG_DEBUG) Log.e(TAG, " onRequestPermissionsResult");

    if (requestCode == CommonConstants.PERMISSION_CODE_REQUEST_ACCESS_CAMERA) {
        if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
            // rationale
            if (LOG_DEBUG) Log.w(TAG, "denied nope");
            dialogRational();
        } else {
            if (checkSelfPermission()) {
                //allowed
                if (LOG_DEBUG) Log.v(TAG, "onGranted: Permission");

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        if (getFragmentManager() != null) {


                            //GO to your scan fragment
                        }
                    }
                }, 200);

            } else {
                //set to never ask again
                if (LOG_DEBUG) Log.w(TAG, "set to never ask again never");

                //TODO DIALOG TO GO TO SETTINGS
                UtilDialog.settingDialog(mInflatedView.getContext());
            }
        }
    }
}

private void dialogRational() {
    if (LOG_DEBUG) Log.d(TAG, "dialogRational: ");
    new AlertDialog.Builder(mInflatedView.getContext())
            .setCancelable(false).setTitle("Warning")
            .setMessage("You must grant the permission, " +
                    "if denied, then go to Setting to activate manually ")
            .setPositiveButton("GRANT ", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                    requestPermission();
                }
            })
            .setNeutralButton("DISMISS", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            }).show();
}

//init
public void initPermission() {
    if (LOG_DEBUG) Log.d(TAG, "initPermission: ");
    requestPermission();

}

//request
private void requestPermission() {
    if (LOG_DEBUG) Log.d(TAG, " requestPermission");
    requestPermissions(new String[]{Manifest.permission.CAMERA}
            , CommonConstants.PERMISSION_CODE_REQUEST_ACCESS_CAMERA);
}

// this one : never ask again
private boolean checkSelfPermission() {
    if (LOG_DEBUG) Log.d(TAG, " checkSelfPermission");
    return ContextCompat.checkSelfPermission(mInflatedView.getContext(), Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED;

}

and use these in manifest

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" /> 
hemen
  • 1,460
  • 2
  • 16
  • 35